Proyecto final HTML + CSS: crear una página web completa y responsive

Proyecto final de HTML y CSS: construí una landing page completa y responsive desde cero usando Flexbox, Grid, media queries y posicionamiento.

En esta serie aprendimos HTML y CSS desde sus fundamentos hasta Flexbox, Grid, responsive design y posicionamiento. Ahora vamos a integrar todo en un proyecto completo.

El objetivo será construir una landing page responsive para una academia ficticia llamada CodeStart.

Importante: este proyecto utiliza solamente HTML y CSS. Todavía no hay lógica ni interacción programada con JavaScript.

Qué vamos a construir

La página tendrá:

  • cabecera con navegación;
  • sección principal o hero;
  • tarjetas de cursos;
  • sección de beneficios;
  • llamada a la acción;
  • pie de página;
  • diseño responsive;
  • Flexbox y CSS Grid;
  • posicionamiento y elementos decorativos.

Estructura de archivos

Creá una carpeta para el proyecto y dentro guardá estos archivos:

codestart/
|
|-- index.html
|-- styles.css

Recordá que el archivo HTML debe guardarse realmente con extensión .html. Por ejemplo: index.html.

Paso 1: crear el HTML

Este será nuestro archivo index.html completo:

<!DOCTYPE html>
<html lang="es">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>CodeStart - Aprendé desarrollo web</title>
    <link rel="stylesheet" href="styles.css">
</head>

<body>

    <header class="cabecera">
        <div class="contenedor cabecera-interior">

            <a href="#" class="logo">
                CodeStart
            </a>

            <nav class="menu">
                <a href="#cursos">Cursos</a>
                <a href="#beneficios">Beneficios</a>
                <a href="#contacto">Contacto</a>
            </nav>

        </div>
    </header>

    <main>

        <section class="hero">

            <div class="contenedor hero-grid">

                <div class="hero-contenido">

                    <span class="etiqueta">
                        Aprendé paso a paso
                    </span>

                    <h1>
                        Empezá hoy tu camino en desarrollo web
                    </h1>

                    <p>
                        Aprendé HTML, CSS y JavaScript con ejercicios,
                        proyectos y explicaciones claras.
                    </p>

                    <a href="#cursos" class="boton">
                        Ver cursos
                    </a>

                </div>

                <div class="hero-tarjeta">

                    <span class="badge">
                        Ruta recomendada
                    </span>

                    <h2>Desarrollo Web</h2>

                    <ul>
                        <li>HTML</li>
                        <li>CSS</li>
                        <li>JavaScript</li>
                    </ul>

                </div>

            </div>

        </section>

        <section id="cursos" class="seccion">

            <div class="contenedor">

                <div class="titulo-seccion">
                    <span>Cursos</span>
                    <h2>Empezá por los fundamentos</h2>
                    <p>
                        Una ruta progresiva para aprender desde cero.
                    </p>
                </div>

                <div class="grid-cursos">

                    <article class="curso">
                        <span class="numero">01</span>
                        <h3>HTML</h3>
                        <p>
                            Aprendé a estructurar correctamente una página web.
                        </p>
                    </article>

                    <article class="curso">
                        <span class="numero">02</span>
                        <h3>CSS</h3>
                        <p>
                            Diseñá interfaces, layouts y sitios responsive.
                        </p>
                    </article>

                    <article class="curso">
                        <span class="numero">03</span>
                        <h3>JavaScript</h3>
                        <p>
                            Incorporá comportamiento e interacción a tus páginas.
                        </p>
                    </article>

                </div>

            </div>

        </section>

        <section id="beneficios" class="seccion beneficios">

            <div class="contenedor beneficios-grid">

                <div>
                    <span class="subtitulo">Por qué aprender acá</span>
                    <h2>Aprender haciendo</h2>

                    <p>
                        La mejor forma de entender desarrollo web es escribir
                        código, cometer errores y resolver problemas reales.
                    </p>
                </div>

                <div class="lista-beneficios">

                    <article>
                        <h3>Ejemplos claros</h3>
                        <p>Código explicado paso a paso.</p>
                    </article>

                    <article>
                        <h3>Práctica constante</h3>
                        <p>Ejercicios para consolidar cada concepto.</p>
                    </article>

                    <article>
                        <h3>Proyectos reales</h3>
                        <p>Integración de conocimientos en proyectos completos.</p>
                    </article>

                </div>

            </div>

        </section>

        <section class="cta">

            <div class="contenedor cta-interior">

                <div>
                    <h2>¿Listo para empezar?</h2>
                    <p>
                        El mejor momento para practicar es ahora.
                    </p>
                </div>

                <a href="#cursos" class="boton boton-claro">
                    Comenzar
                </a>

            </div>

        </section>

    </main>

    <footer id="contacto" class="footer">

        <div class="contenedor footer-interior">

            <p>
                © CodeStart
            </p>

            <p>
                Proyecto educativo HTML + CSS
            </p>

        </div>

    </footer>

</body>
</html>

Paso 2: crear los estilos base

Ahora abrí styles.css.

Empezamos normalizando el modelo de caja y definiendo estilos generales:

*, *::before, *::after {
    box-sizing: border-box;
}

html {
    scroll-behavior: smooth;
}

body {
    margin: 0;
    font-family: Arial, Helvetica, sans-serif;
    color: #1f2937;
    background-color: #ffffff;
    line-height: 1.6;
}

img {
    max-width: 100%;
    height: auto;
}

a {
    color: inherit;
}

.contenedor {
    width: 90%;
    max-width: 1180px;
    margin: 0 auto;
}

Paso 3: cabecera y navegación

Usaremos Flexbox para distribuir el logo y el menú.

.cabecera {
    position: sticky;
    top: 0;
    z-index: 100;
    background-color: rgba(255, 255, 255, 0.96);
    border-bottom: 1px solid #e5e7eb;
}

.cabecera-interior {
    display: flex;
    flex-direction: column;
    gap: 1rem;
    padding: 1rem 0;
}

.logo {
    color: #007bff;
    font-size: 1.5rem;
    font-weight: 700;
    text-decoration: none;
}

.menu {
    display: flex;
    flex-wrap: wrap;
    gap: 1rem;
}

.menu a {
    text-decoration: none;
    font-weight: 600;
}

Paso 4: sección principal

El hero combinará Grid, tipografía adaptable y un fondo degradado.

.hero {
    padding: clamp(4rem, 9vw, 8rem) 0;
    color: white;
    background: linear-gradient(135deg, #0b1220, #1e3a8a);
}

.hero-grid {
    display: grid;
    grid-template-columns: 1fr;
    gap: 3rem;
    align-items: center;
}

.hero h1 {
    max-width: 760px;
    margin: 1rem 0;
    font-size: clamp(2.5rem, 7vw, 4.8rem);
    line-height: 1.05;
}

.hero-contenido p {
    max-width: 650px;
    margin-bottom: 2rem;
    font-size: 1.1rem;
    color: #dbeafe;
}

.etiqueta,
.subtitulo {
    display: inline-block;
    color: #93c5fd;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.08em;
}

.boton {
    display: inline-block;
    padding: 0.9rem 1.4rem;
    color: white;
    background-color: #007bff;
    border-radius: 8px;
    text-decoration: none;
    font-weight: 700;
}

Paso 5: tarjeta destacada y posicionamiento

Vamos a aprovechar position: relative y absolute para ubicar una etiqueta.

.hero-tarjeta {
    position: relative;
    padding: 2rem;
    color: #0b1220;
    background-color: white;
    border-radius: 16px;
}

.hero-tarjeta ul {
    margin: 1.5rem 0 0;
    padding-left: 1.2rem;
}

.badge {
    position: absolute;
    top: -14px;
    right: 20px;
    padding: 0.45rem 0.8rem;
    color: #0b1220;
    background-color: #fbbf24;
    border-radius: 999px;
    font-size: 0.85rem;
    font-weight: 700;
}

Paso 6: sección de cursos con CSS Grid

.seccion {
    padding: clamp(4rem, 8vw, 7rem) 0;
}

.titulo-seccion {
    max-width: 680px;
    margin-bottom: 2.5rem;
}

.titulo-seccion > span {
    color: #007bff;
    font-weight: 700;
    text-transform: uppercase;
}

.titulo-seccion h2 {
    margin: 0.5rem 0;
    font-size: clamp(2rem, 4vw, 3rem);
}

.grid-cursos {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
    gap: 1.5rem;
}

.curso {
    position: relative;
    padding: 2rem;
    border: 1px solid #e5e7eb;
    border-radius: 14px;
    background-color: #ffffff;
}

.numero {
    display: inline-block;
    margin-bottom: 1rem;
    color: #007bff;
    font-weight: 700;
}

.curso h3 {
    margin: 0 0 0.7rem;
    font-size: 1.5rem;
}

Paso 7: beneficios

.beneficios {
    background-color: #f8fafc;
}

.beneficios-grid {
    display: grid;
    grid-template-columns: 1fr;
    gap: 3rem;
}

.beneficios h2 {
    margin: 0.5rem 0 1rem;
    font-size: clamp(2rem, 4vw, 3rem);
}

.lista-beneficios {
    display: grid;
    gap: 1rem;
}

.lista-beneficios article {
    padding: 1.4rem;
    background-color: white;
    border-left: 4px solid #007bff;
    border-radius: 8px;
}

.lista-beneficios h3 {
    margin-top: 0;
}

Paso 8: llamada a la acción

.cta {
    padding: 3rem 0;
    color: white;
    background-color: #007bff;
}

.cta-interior {
    display: flex;
    flex-direction: column;
    gap: 1.5rem;
    align-items: flex-start;
}

.cta h2,
.cta p {
    margin-top: 0;
}

.boton-claro {
    color: #0b1220;
    background-color: white;
}

Paso 9: footer

.footer {
    padding: 2rem 0;
    color: #cbd5e1;
    background-color: #0b1220;
}

.footer-interior {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
}

.footer p {
    margin: 0;
}

Paso 10: hacerlo responsive

El diseño base fue pensado primero para pantallas pequeñas. Ahora ampliamos el layout cuando tenemos más espacio.

@media (min-width: 768px) {

    .cabecera-interior {
        flex-direction: row;
        align-items: center;
        justify-content: space-between;
    }

    .hero-grid {
        grid-template-columns: minmax(0, 1.5fr) minmax(280px, 0.8fr);
    }

    .beneficios-grid {
        grid-template-columns: 1fr 1fr;
        align-items: start;
    }

    .cta-interior {
        flex-direction: row;
        align-items: center;
        justify-content: space-between;
    }

    .footer-interior {
        flex-direction: row;
        justify-content: space-between;
        align-items: center;
    }
}

CSS completo

Si preferís comparar el resultado final, este es el archivo styles.css completo:

*, *::before, *::after {
    box-sizing: border-box;
}

html {
    scroll-behavior: smooth;
}

body {
    margin: 0;
    font-family: Arial, Helvetica, sans-serif;
    color: #1f2937;
    background-color: #ffffff;
    line-height: 1.6;
}

img {
    max-width: 100%;
    height: auto;
}

a {
    color: inherit;
}

.contenedor {
    width: 90%;
    max-width: 1180px;
    margin: 0 auto;
}

.cabecera {
    position: sticky;
    top: 0;
    z-index: 100;
    background-color: rgba(255, 255, 255, 0.96);
    border-bottom: 1px solid #e5e7eb;
}

.cabecera-interior {
    display: flex;
    flex-direction: column;
    gap: 1rem;
    padding: 1rem 0;
}

.logo {
    color: #007bff;
    font-size: 1.5rem;
    font-weight: 700;
    text-decoration: none;
}

.menu {
    display: flex;
    flex-wrap: wrap;
    gap: 1rem;
}

.menu a {
    text-decoration: none;
    font-weight: 600;
}

.hero {
    padding: clamp(4rem, 9vw, 8rem) 0;
    color: white;
    background: linear-gradient(135deg, #0b1220, #1e3a8a);
}

.hero-grid {
    display: grid;
    grid-template-columns: 1fr;
    gap: 3rem;
    align-items: center;
}

.hero h1 {
    max-width: 760px;
    margin: 1rem 0;
    font-size: clamp(2.5rem, 7vw, 4.8rem);
    line-height: 1.05;
}

.hero-contenido p {
    max-width: 650px;
    margin-bottom: 2rem;
    font-size: 1.1rem;
    color: #dbeafe;
}

.etiqueta,
.subtitulo {
    display: inline-block;
    color: #93c5fd;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.08em;
}

.boton {
    display: inline-block;
    padding: 0.9rem 1.4rem;
    color: white;
    background-color: #007bff;
    border-radius: 8px;
    text-decoration: none;
    font-weight: 700;
}

.hero-tarjeta {
    position: relative;
    padding: 2rem;
    color: #0b1220;
    background-color: white;
    border-radius: 16px;
}

.hero-tarjeta ul {
    margin: 1.5rem 0 0;
    padding-left: 1.2rem;
}

.badge {
    position: absolute;
    top: -14px;
    right: 20px;
    padding: 0.45rem 0.8rem;
    color: #0b1220;
    background-color: #fbbf24;
    border-radius: 999px;
    font-size: 0.85rem;
    font-weight: 700;
}

.seccion {
    padding: clamp(4rem, 8vw, 7rem) 0;
}

.titulo-seccion {
    max-width: 680px;
    margin-bottom: 2.5rem;
}

.titulo-seccion > span {
    color: #007bff;
    font-weight: 700;
    text-transform: uppercase;
}

.titulo-seccion h2,
.beneficios h2 {
    margin: 0.5rem 0 1rem;
    font-size: clamp(2rem, 4vw, 3rem);
}

.grid-cursos {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
    gap: 1.5rem;
}

.curso {
    position: relative;
    padding: 2rem;
    border: 1px solid #e5e7eb;
    border-radius: 14px;
    background-color: #ffffff;
}

.numero {
    display: inline-block;
    margin-bottom: 1rem;
    color: #007bff;
    font-weight: 700;
}

.curso h3 {
    margin: 0 0 0.7rem;
    font-size: 1.5rem;
}

.beneficios {
    background-color: #f8fafc;
}

.beneficios-grid {
    display: grid;
    grid-template-columns: 1fr;
    gap: 3rem;
}

.lista-beneficios {
    display: grid;
    gap: 1rem;
}

.lista-beneficios article {
    padding: 1.4rem;
    background-color: white;
    border-left: 4px solid #007bff;
    border-radius: 8px;
}

.lista-beneficios h3 {
    margin-top: 0;
}

.cta {
    padding: 3rem 0;
    color: white;
    background-color: #007bff;
}

.cta-interior {
    display: flex;
    flex-direction: column;
    gap: 1.5rem;
    align-items: flex-start;
}

.cta h2,
.cta p {
    margin-top: 0;
}

.boton-claro {
    color: #0b1220;
    background-color: white;
}

.footer {
    padding: 2rem 0;
    color: #cbd5e1;
    background-color: #0b1220;
}

.footer-interior {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
}

.footer p {
    margin: 0;
}

@media (min-width: 768px) {

    .cabecera-interior {
        flex-direction: row;
        align-items: center;
        justify-content: space-between;
    }

    .hero-grid {
        grid-template-columns: minmax(0, 1.5fr) minmax(280px, 0.8fr);
    }

    .beneficios-grid {
        grid-template-columns: 1fr 1fr;
        align-items: start;
    }

    .cta-interior {
        flex-direction: row;
        align-items: center;
        justify-content: space-between;
    }

    .footer-interior {
        flex-direction: row;
        justify-content: space-between;
        align-items: center;
    }
}

Qué conceptos estamos integrando

Este proyecto utiliza prácticamente toda la ruta de CSS:

  • selectores;
  • clases;
  • modelo de caja;
  • tipografías;
  • colores y fondos;
  • unidades relativas;
  • clamp();
  • Flexbox;
  • CSS Grid;
  • gap;
  • minmax();
  • responsive design;
  • media queries;
  • mobile-first;
  • position: sticky;
  • position: absolute;
  • z-index.

Cómo probar el proyecto

Guardá ambos archivos y abrí index.html con tu navegador.

Después:

  • agrandá y achicá la ventana;
  • probá el modo responsive de las herramientas de desarrollo;
  • verificá que no aparezca scroll horizontal;
  • observá cómo cambia el hero a partir de 768px;
  • comprobá cómo las tarjetas se reorganizan automáticamente.

Mejoras para practicar por tu cuenta

Podés continuar el proyecto agregando:

  • una imagen real en el hero;
  • más tarjetas;
  • una sección de testimonios;
  • un formulario de contacto;
  • estados :hover para enlaces y botones;
  • transiciones CSS;
  • un menú específico para pantallas pequeñas;
  • una segunda página;
  • una paleta de colores propia.

HTML, CSS y el siguiente paso

Con HTML ya podemos definir la estructura y el significado del contenido.

Con CSS podemos controlar la presentación, el layout y la adaptación visual.

Pero todavía nuestro sitio no puede reaccionar realmente a acciones del usuario, tomar decisiones o modificar dinámicamente el contenido.

Ahí entra JavaScript.

HTML       → estructura y contenido
CSS        → estilos y presentación
JavaScript → comportamiento e interacción

Ruta completada

Si llegaste hasta acá, ya recorriste una base muy sólida de HTML y CSS.

La guía anterior fue:

Posicionamiento en CSS: static, relative, absolute, fixed, sticky y z-index

El próximo gran paso de la ruta será:

Introducción a JavaScript: qué es, cómo funciona y para qué se utiliza.


¿Te sirvió este proyecto? ☕

Si este contenido te ayudó a aprender desarrollo web, podés apoyar a Club Programador.

🇦🇷 Apoyar desde Argentina

☕ Invitame un café con Mercado Pago

🌎 Apoyar desde otro país

☕ Apoyar con PayPal

Posicionamiento en CSS: static, relative, absolute, fixed, sticky y z-index

Aprendé posicionamiento en CSS: static, relative, absolute, fixed, sticky, z-index, ancestros posicionados y contextos de apilamiento con ejemplos prácticos.

Ya vimos cómo construir layouts con Flexbox y Grid y cómo adaptarlos a distintos tamaños de pantalla. Ahora toca entender cómo posicionar elementos con más precisión dentro de una página.

Para eso CSS ofrece la propiedad position.

El flujo normal del documento

Antes de usar posicionamiento, conviene entender que los elementos HTML normalmente participan del flujo normal del documento.

Eso significa que ocupan espacio y empujan a los elementos siguientes según su tipo y tamaño.

<div class="caja">Caja 1</div>
<div class="caja">Caja 2</div>
<div class="caja">Caja 3</div>

Sin reglas especiales, estas cajas se ubicarán una después de otra.

position: static

static es el valor por defecto.

.caja {
    position: static;
}

El elemento permanece en el flujo normal y propiedades como top, right, bottom y left no tienen efecto.

position: relative

Con relative, el elemento sigue ocupando su lugar original, pero podemos desplazarlo visualmente.

.caja {
    position: relative;
    top: 20px;
    left: 10px;
}

El espacio original del elemento sigue reservado.

top, right, bottom y left

Estas propiedades permiten desplazar un elemento posicionado:

top
right
bottom
left

Su efecto depende del valor de position.

position: absolute

Un elemento con position: absolute sale del flujo normal del documento.

.badge {
    position: absolute;
    top: 10px;
    right: 10px;
}

Eso significa que deja de reservar espacio en la posición que ocupaba originalmente.

¿Respecto de qué se posiciona un elemento absolute?

Este es uno de los puntos más importantes.

Un elemento con position: absolute se posiciona respecto del ancestro posicionado más cercano.

Por eso es muy frecuente combinar:

.tarjeta {
    position: relative;
}
.badge {
    position: absolute;
    top: 10px;
    right: 10px;
}

HTML:

<article class="tarjeta">

    <span class="badge">
        Nuevo
    </span>

    <h2>Curso de CSS</h2>

    <p>
        Aprendé diseño web.
    </p>

</article>

En este caso, el badge se posiciona tomando como referencia la tarjeta.

¿Qué pasa si no hay un ancestro posicionado?

Si no encuentra un ancestro con una posición distinta de static, el elemento puede terminar posicionándose respecto de un contenedor superior, normalmente relacionado con el documento.

Por eso suele ser buena práctica definir position: relative en el contenedor que queremos usar como referencia.

Ejemplo: etiqueta sobre una imagen

HTML:

<div class="producto">

    <img src="producto.jpg" alt="Producto">

    <span class="oferta">
        -20%
    </span>

</div>

CSS:

.producto {
    position: relative;
    display: inline-block;
}
.oferta {
    position: absolute;
    top: 10px;
    left: 10px;
    padding: 0.4rem 0.7rem;
    background-color: red;
    color: white;
    border-radius: 6px;
}

position: fixed

fixed posiciona el elemento respecto del viewport.

El elemento permanece en el mismo lugar aunque hagamos scroll.

.boton-flotante {
    position: fixed;
    right: 20px;
    bottom: 20px;
}

Es frecuente en:

  • botones flotantes;
  • acciones rápidas;
  • barras persistentes;
  • botones para volver arriba.

Ejemplo: botón flotante

HTML:

<a href="#inicio" class="boton-flotante">
    ↑
</a>

CSS:

.boton-flotante {
    position: fixed;
    right: 1.5rem;
    bottom: 1.5rem;
    width: 48px;
    height: 48px;
    display: flex;
    align-items: center;
    justify-content: center;
    background-color: #007bff;
    color: white;
    border-radius: 50%;
    text-decoration: none;
}

position: sticky

sticky combina características del posicionamiento relativo y fijo.

El elemento se comporta normalmente hasta alcanzar una posición determinada y luego permanece visible mientras su contenedor lo permita.

.cabecera {
    position: sticky;
    top: 0;
}

Ejemplo: cabecera sticky

<header class="cabecera">
    <h1>Club Programador</h1>
</header>
.cabecera {
    position: sticky;
    top: 0;
    background-color: white;
    padding: 1rem;
    border-bottom: 1px solid #ddd;
}

Cuando hacemos scroll, la cabecera puede permanecer pegada a la parte superior.

Sticky necesita una referencia

Para que sticky funcione, normalmente debemos indicar al menos una posición como:

top: 0;

Además, ciertos valores de overflow en elementos antecesores pueden cambiar o impedir el comportamiento esperado.

z-index

Cuando varios elementos se superponen, necesitamos decidir cuál aparece por encima.

Para eso utilizamos z-index.

.cabecera {
    position: sticky;
    top: 0;
    z-index: 100;
}

En términos generales, un valor mayor puede hacer que un elemento aparezca por encima de otro dentro de un contexto de apilamiento compatible.

No alcanza siempre con poner un z-index enorme

Un error común es pensar que:

z-index: 999999;

resolverá cualquier problema.

CSS trabaja con contextos de apilamiento. Un elemento puede quedar limitado por el contexto creado por alguno de sus ancestros.

Por ahora, lo importante es saber que z-index no funciona como una única lista global para toda la página.

Contexto de apilamiento explicado de forma simple

Podemos imaginar distintos grupos o capas independientes.

Un elemento puede tener un z-index alto dentro de su grupo, pero seguir estando por debajo de otro grupo completo.

Propiedades como posicionamiento con z-index, transformaciones y opacidad pueden crear nuevos contextos de apilamiento.

Ejemplo de superposición

.fondo {
    position: absolute;
    z-index: 1;
}
.contenido {
    position: relative;
    z-index: 2;
}

Si ambos pertenecen al mismo contexto de apilamiento, el contenido aparecerá por encima.

Centrar con absolute y transform

Una técnica clásica para centrar un elemento absolutamente posicionado es:

.modal {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
}

Hoy muchas situaciones de centrado se resuelven más fácilmente con Flexbox o Grid, pero esta técnica sigue siendo útil en ciertos casos.

Ejemplo: modal básico

HTML:

<div class="overlay">

    <div class="modal">

        <h2>Confirmación</h2>

        <p>
            ¿Deseás continuar?
        </p>

    </div>

</div>

CSS:

.overlay {
    position: fixed;
    inset: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    background-color: rgba(0, 0, 0, 0.6);
}
.modal {
    width: 90%;
    max-width: 500px;
    padding: 2rem;
    background-color: white;
    border-radius: 12px;
}

La propiedad inset

inset permite abreviar top, right, bottom y left.

Por ejemplo:

.overlay {
    position: fixed;
    inset: 0;
}

equivale aproximadamente a:

top: 0;
right: 0;
bottom: 0;
left: 0;

Cuándo usar cada tipo de position

static   → comportamiento normal
relative → referencia o pequeño desplazamiento
absolute → posición respecto de un ancestro
fixed    → posición respecto del viewport
sticky   → se fija al hacer scroll dentro de ciertos límites

Position no reemplaza Flexbox ni Grid

Un error frecuente al comenzar es intentar construir todo el layout usando position: absolute.

Para distribuir secciones, columnas, tarjetas o menús, normalmente Flexbox y Grid son mejores herramientas.

absolute resulta especialmente útil para elementos superpuestos o ubicaciones puntuales.

Ejemplo combinado

HTML:

<article class="curso">

    <span class="etiqueta">
        Destacado
    </span>

    <h2>Curso de CSS</h2>

    <p>
        Aprendé CSS paso a paso.
    </p>

    <a href="#">
        Ver curso
    </a>

</article>

CSS:

.curso {
    position: relative;
    display: flex;
    flex-direction: column;
    gap: 1rem;
    padding: 2rem;
    border: 1px solid #ddd;
    border-radius: 12px;
}
.etiqueta {
    position: absolute;
    top: 1rem;
    right: 1rem;
    padding: 0.35rem 0.6rem;
    background-color: #007bff;
    color: white;
    border-radius: 6px;
}

Errores comunes

  • usar absolute para construir toda la página;
  • olvidar definir position: relative en el contenedor de referencia;
  • creer que un elemento absolute sigue reservando espacio;
  • usar fixed para elementos grandes que tapan contenido;
  • usar sticky sin definir top;
  • aumentar z-index indefinidamente sin entender el contexto de apilamiento;
  • superponer contenido importante en pantallas pequeñas;
  • usar posicionamiento cuando Flexbox o Grid resolverían mejor el problema.

Ejercicio para practicar

Partiendo de:

<article class="producto">

    <span class="nuevo">
        Nuevo
    </span>

    <h2>Curso de CSS</h2>

    <p>
        Guía completa de estilos.
    </p>

</article>

Intentá:

  • hacer que .producto sea el contenedor de referencia;
  • ubicar la etiqueta .nuevo arriba a la derecha;
  • agregar un botón fijo abajo a la derecha de la pantalla;
  • crear una cabecera sticky;
  • experimentar con z-index para controlar superposiciones.

Qué aprendimos

  • flujo normal del documento;
  • position: static;
  • position: relative;
  • position: absolute;
  • ancestro posicionado;
  • top, right, bottom y left;
  • position: fixed;
  • position: sticky;
  • z-index;
  • introducción a contextos de apilamiento;
  • inset;
  • cuándo conviene usar posicionamiento.

Seguí aprendiendo CSS

La guía anterior es:

Responsive Design en CSS: media queries, breakpoints y mobile-first

El siguiente paso es integrar todo lo aprendido en un proyecto final HTML + CSS:

Proyecto final HTML + CSS: crear una página web completa y responsive →


¿Te sirvió esta guía? ☕

Si este contenido te ayudó a aprender desarrollo web, podés apoyar a Club Programador.

🇦🇷 Apoyar desde Argentina

☕ Invitame un café con Mercado Pago

🌎 Apoyar desde otro país

☕ Apoyar con PayPal

Responsive Design en CSS: media queries, breakpoints y mobile-first

Aprendé Responsive Design en CSS: media queries, breakpoints, enfoque mobile-first, Flexbox y Grid responsive, imágenes fluidas y clamp().

Después de aprender Flexbox y CSS Grid, ya tenemos herramientas potentes para construir layouts. El siguiente paso es hacer que esos diseños se adapten correctamente a distintos tamaños de pantalla.

Eso es lo que buscamos con el diseño responsive.

¿Qué significa responsive?

Un diseño responsive se adapta al espacio disponible sin obligar al usuario a hacer zoom, desplazarse horizontalmente o luchar con elementos demasiado pequeños.

La misma página debería poder funcionar correctamente en:

  • celulares;
  • tablets;
  • notebooks;
  • monitores grandes.

No se trata simplemente de “hacer una versión para celular”, sino de crear una interfaz flexible.

La etiqueta viewport

Antes de trabajar con media queries, nuestro HTML debería incluir esta etiqueta dentro de head:

<meta name="viewport" content="width=device-width, initial-scale=1.0">

Esta configuración indica al navegador móvil que utilice el ancho real del dispositivo como referencia.

¿Qué es una media query?

Una media query permite aplicar reglas CSS solamente cuando se cumple determinada condición.

Por ejemplo:

@media (min-width: 768px) {
    .contenedor {
        max-width: 720px;
    }
}

Estas reglas se aplican cuando el viewport tiene al menos 768px de ancho.

min-width y max-width

Las dos condiciones más utilizadas son:

@media (min-width: 768px)

y:

@media (max-width: 767px)

min-width significa “desde este ancho en adelante”.

max-width significa “hasta este ancho”.

¿Qué es mobile-first?

El enfoque mobile-first consiste en escribir primero los estilos para pantallas pequeñas y agregar mejoras a medida que aumenta el espacio disponible.

Por ejemplo:

.menu {
    display: flex;
    flex-direction: column;
    gap: 1rem;
}

Luego, para pantallas más grandes:

@media (min-width: 768px) {
    .menu {
        flex-direction: row;
    }
}

Así partimos de una experiencia sencilla para celular y ampliamos el diseño progresivamente.

Breakpoints

Un breakpoint es un punto en el que decidimos cambiar parte del diseño.

No existe una lista universal que deba usarse siempre. Lo ideal es elegirlos según el momento en que el contenido deja de verse bien.

Como referencia inicial, pueden aparecer valores como:

576px
768px
992px
1200px

Pero no conviene diseñar pensando solamente en modelos concretos de dispositivos.

Ejemplo: tarjetas responsive con Flexbox

HTML:

<section class="cursos">

    <article class="tarjeta">
        <h2>HTML</h2>
        <p>Estructura web.</p>
    </article>

    <article class="tarjeta">
        <h2>CSS</h2>
        <p>Estilos y diseño.</p>
    </article>

    <article class="tarjeta">
        <h2>JavaScript</h2>
        <p>Interacción.</p>
    </article>

</section>

CSS:

.cursos {
    display: flex;
    flex-direction: column;
    gap: 1rem;
}
@media (min-width: 768px) {
    .cursos {
        flex-direction: row;
        flex-wrap: wrap;
    }

    .tarjeta {
        flex: 1 1 280px;
    }
}

Ejemplo responsive con CSS Grid

Grid puede resolver muchos diseños responsive con muy pocas reglas:

.galeria {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
    gap: 1.5rem;
}

En este caso, el navegador crea tantas columnas como entren, sin necesidad de media queries para cada tamaño.

Imágenes responsive

Una imagen puede desbordar su contenedor si tiene un ancho mayor que la pantalla.

Una regla muy habitual es:

img {
    max-width: 100%;
    height: auto;
}

Así la imagen nunca supera el ancho disponible y conserva su proporción.

Contenedores fluidos

Un patrón frecuente es combinar porcentaje y ancho máximo:

.contenedor {
    width: 90%;
    max-width: 1200px;
    margin: 0 auto;
}

Esto permite que el contenido use gran parte de la pantalla en dispositivos pequeños, pero evita que se vuelva demasiado ancho en monitores grandes.

Tipografía responsive

También podemos adaptar tamaños de texto.

h1 {
    font-size: 2rem;
}
@media (min-width: 768px) {
    h1 {
        font-size: 3rem;
    }
}

clamp()

CSS moderno ofrece clamp(), que permite definir un valor mínimo, uno flexible y uno máximo.

h1 {
    font-size: clamp(2rem, 5vw, 4rem);
}

Esto significa que el tamaño podrá crecer con el viewport, pero nunca será menor que 2rem ni mayor que 4rem.

Espaciados adaptativos

clamp() también puede utilizarse para padding y márgenes:

.hero {
    padding: clamp(2rem, 6vw, 6rem) 1.5rem;
}

Menú responsive simple

HTML:

<nav class="menu">
    <a href="#">Inicio</a>
    <a href="#">HTML</a>
    <a href="#">CSS</a>
    <a href="#">Contacto</a>
</nav>

CSS mobile-first:

.menu {
    display: flex;
    flex-direction: column;
    gap: 0.75rem;
}
@media (min-width: 768px) {
    .menu {
        flex-direction: row;
        gap: 2rem;
    }
}

Ocultar elementos según el tamaño

Es posible ocultar elementos con media queries:

@media (max-width: 767px) {
    .solo-escritorio {
        display: none;
    }
}

Pero conviene no abusar de esta técnica. Si el contenido es importante, normalmente debería seguir estando disponible.

Media queries por orientación

También podemos detectar orientación:

@media (orientation: landscape) {
    .galeria {
        grid-template-columns: repeat(3, 1fr);
    }
}

Preferencias del usuario

Las media queries también pueden consultar ciertas preferencias del sistema.

Por ejemplo, para reducir animaciones:

@media (prefers-reduced-motion: reduce) {
    * {
        scroll-behavior: auto;
    }
}

Esto es útil para mejorar accesibilidad.

Evitar el scroll horizontal

Un problema común en móviles es que algún elemento sea más ancho que la pantalla.

Las causas frecuentes son:

  • anchos fijos demasiado grandes;
  • imágenes sin max-width;
  • tablas muy anchas;
  • contenedores con padding y tamaños mal calculados;
  • texto o código que no puede ajustarse.

La solución correcta es encontrar el elemento que desborda. No conviene ocultar el problema simplemente agregando overflow-x: hidden al sitio completo.

Tablas en pantallas pequeñas

Las tablas pueden necesitar desplazamiento horizontal controlado.

HTML:

<div class="tabla-responsive">
    <table>
        ...
    </table>
</div>

CSS:

.tabla-responsive {
    overflow-x: auto;
}

Un layout completo mobile-first

HTML:

<div class="pagina">

    <header class="cabecera">
        <h1>Club Programador</h1>
    </header>

    <main class="contenido">

        <article>
            <h2>Aprender CSS</h2>
            <p>Contenido principal.</p>
        </article>

        <aside>
            Recursos relacionados
        </aside>

    </main>

</div>

CSS:

.pagina {
    width: 90%;
    max-width: 1200px;
    margin: 0 auto;
}
.contenido {
    display: grid;
    grid-template-columns: 1fr;
    gap: 2rem;
}
@media (min-width: 900px) {
    .contenido {
        grid-template-columns: 2fr 1fr;
    }
}

En móvil existe una sola columna. Cuando hay espacio suficiente, aparece una segunda columna para el contenido lateral.

Probar distintos tamaños

No alcanza con reducir la ventana una sola vez.

Conviene probar:

  • pantallas muy angostas;
  • anchos intermedios;
  • tablets;
  • escritorio;
  • contenido más largo de lo esperado;
  • zoom del navegador.

Las herramientas de desarrollo del navegador permiten simular distintos tamaños de viewport.

No diseñar para dispositivos específicos

Un error común es pensar:

celular = 375px
tablet  = 768px
PC      = 1200px

En realidad existen muchísimos tamaños intermedios.

Los breakpoints deberían aparecer donde el diseño los necesita, no solamente donde una tabla de dispositivos lo indica.

Errores comunes

  • olvidar la etiqueta viewport;
  • crear una versión de escritorio y después intentar “achicarla” a la fuerza;
  • usar demasiados breakpoints;
  • depender exclusivamente de anchos fijos;
  • no permitir que Flexbox haga wrap;
  • no usar Grid flexible cuando corresponde;
  • dejar imágenes con ancho fijo;
  • ocultar contenido importante en móvil;
  • elegir breakpoints solamente por modelos de dispositivos;
  • no probar anchos intermedios.

Ejercicio para practicar

Partiendo de:

<section class="productos">

    <article class="producto">
        <h2>Producto 1</h2>
        <p>Descripción.</p>
    </article>

    <article class="producto">
        <h2>Producto 2</h2>
        <p>Descripción.</p>
    </article>

    <article class="producto">
        <h2>Producto 3</h2>
        <p>Descripción.</p>
    </article>

</section>

Intentá crear un diseño que:

  • muestre una columna en pantallas pequeñas;
  • muestre dos columnas en un ancho intermedio;
  • muestre tres columnas cuando haya espacio suficiente;
  • utilice gap;
  • mantenga un ancho máximo para el contenido;
  • use tipografía adaptable con clamp();
  • no genere scroll horizontal.

Qué aprendimos

  • qué significa responsive;
  • etiqueta viewport;
  • media queries;
  • min-width y max-width;
  • mobile-first;
  • breakpoints;
  • Flexbox responsive;
  • Grid responsive;
  • imágenes fluidas;
  • contenedores fluidos;
  • clamp();
  • orientación y preferencias del usuario;
  • cómo evitar desbordes horizontales.

Seguí aprendiendo CSS

La guía anterior es:

CSS Grid: filas, columnas, gap, fr, repeat y minmax paso a paso

El próximo paso será estudiar el posicionamiento en CSS: static, relative, absolute, fixed, sticky y z-index.


¿Te sirvió esta guía? ☕

Si este contenido te ayudó a aprender desarrollo web, podés apoyar a Club Programador.

🇦🇷 Apoyar desde Argentina

☕ Invitame un café con Mercado Pago

🌎 Apoyar desde otro país

☕ Apoyar con PayPal

CSS Grid: filas, columnas, gap, fr, repeat y minmax paso a paso

Aprendé CSS Grid desde cero: filas, columnas, fr, repeat, minmax, gap, auto-fit, áreas y layouts responsive con ejemplos prácticos.

Después de aprender Flexbox, el siguiente sistema fundamental de maquetación en CSS es Grid.

Mientras Flexbox resulta excelente para distribuir elementos principalmente en una dimensión, CSS Grid permite trabajar de forma muy natural con filas y columnas al mismo tiempo.

¿Qué es CSS Grid?

CSS Grid es un sistema de layout bidimensional. Permite definir una cuadrícula y ubicar elementos dentro de filas y columnas.

Para activarlo utilizamos:

.contenedor {
    display: grid;
}

Los hijos directos del contenedor pasan a ser elementos de la cuadrícula.

Primer ejemplo

HTML:

<section class="grid">
    <div>1</div>
    <div>2</div>
    <div>3</div>
    <div>4</div>
</section>

CSS:

.grid {
    display: grid;
    grid-template-columns: 1fr 1fr;
}

Esto crea dos columnas del mismo ancho.

La unidad fr

fr representa una fracción del espacio disponible.

.grid {
    grid-template-columns: 1fr 1fr 1fr;
}

En este caso se crean tres columnas iguales.

También podemos repartir el espacio en proporciones diferentes:

.grid {
    grid-template-columns: 2fr 1fr;
}

La primera columna ocupará aproximadamente el doble que la segunda.

grid-template-columns

Define las columnas de la cuadrícula.

.grid {
    grid-template-columns: 200px 1fr 1fr;
}

Aquí tenemos una primera columna fija de 200px y dos columnas flexibles.

grid-template-rows

Permite definir las filas.

.grid {
    grid-template-rows: 100px 200px;
}

repeat()

Cuando repetimos medidas, podemos simplificar usando repeat().

.grid {
    grid-template-columns: repeat(3, 1fr);
}

Esto equivale a:

grid-template-columns: 1fr 1fr 1fr;

gap

Al igual que en Flexbox, Grid permite separar elementos con gap.

.grid {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 20px;
}

column-gap y row-gap

También podemos controlar cada separación de forma independiente.

.grid {
    column-gap: 30px;
    row-gap: 15px;
}

Columnas responsive con auto-fit

Uno de los patrones más útiles de Grid combina repeat(), auto-fit y minmax().

.grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
    gap: 20px;
}

Esto permite que el navegador cree automáticamente tantas columnas como entren, manteniendo un ancho mínimo de 250px.

minmax()

minmax() define un tamaño mínimo y uno máximo.

minmax(250px, 1fr)

Significa:

  • mínimo: 250px;
  • máximo: una fracción del espacio disponible.

auto-fit vs auto-fill

Ambos ayudan a generar columnas automáticamente.

Como idea inicial:

  • auto-fit puede expandir las columnas existentes para ocupar el espacio disponible;
  • auto-fill mantiene la lógica de las columnas posibles aunque algunas queden vacías.

En muchos diseños de tarjetas, auto-fit es una opción muy práctica.

Ubicar elementos por líneas

Grid numera las líneas que separan filas y columnas.

Podemos decir que un elemento comience en una línea y termine en otra.

.destacada {
    grid-column: 1 / 3;
}

El elemento ocupará desde la línea 1 hasta la 3, es decir, dos columnas.

grid-column

También podemos usar span.

.destacada {
    grid-column: span 2;
}

Esto indica que el elemento debe ocupar dos columnas.

grid-row

La misma lógica se aplica a las filas.

.alto {
    grid-row: span 2;
}

grid-column-start y grid-column-end

La forma abreviada:

grid-column: 1 / 3;

equivale a:

grid-column-start: 1;
grid-column-end: 3;

Alinear elementos en Grid

Grid también permite controlar la alineación.

justify-items

.grid {
    justify-items: center;
}

Alinea los elementos horizontalmente dentro de sus celdas.

align-items

.grid {
    align-items: center;
}

Alinea los elementos verticalmente dentro de sus celdas.

place-items

Podemos combinar ambas:

.grid {
    place-items: center;
}

Alinear toda la cuadrícula

También existen propiedades para distribuir la cuadrícula completa dentro del contenedor:

justify-content
align-content
place-content

Ejemplo de galería

HTML:

<section class="galeria">
    <div class="foto">Foto 1</div>
    <div class="foto">Foto 2</div>
    <div class="foto">Foto 3</div>
    <div class="foto">Foto 4</div>
    <div class="foto">Foto 5</div>
    <div class="foto">Foto 6</div>
</section>

CSS:

.galeria {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
    gap: 1rem;
}
.foto {
    padding: 2rem;
    background-color: #e5e7eb;
    border-radius: 10px;
}

Ejemplo de layout de página

HTML:

<div class="pagina">
    <header>Cabecera</header>
    <aside>Menú lateral</aside>
    <main>Contenido principal</main>
    <footer>Pie de página</footer>
</div>

CSS:

.pagina {
    display: grid;
    grid-template-columns: 250px 1fr;
    grid-template-rows: auto 1fr auto;
    min-height: 100vh;
}
header {
    grid-column: 1 / -1;
}

footer {
    grid-column: 1 / -1;
}

-1 representa la última línea de la cuadrícula.

grid-template-areas

Grid permite asignar nombres a zonas de la página.

.pagina {
    display: grid;
    grid-template-columns: 250px 1fr;
    grid-template-areas: "header header" "sidebar main" "footer footer";
}

Después asignamos cada elemento:

header {
    grid-area: header;
}

aside {
    grid-area: sidebar;
}

main {
    grid-area: main;
}

footer {
    grid-area: footer;
}

Esta sintaxis puede hacer que layouts complejos sean más fáciles de visualizar.

Flexbox vs Grid

No son tecnologías rivales. Se complementan.

Como orientación inicial:

Flexbox → distribución principalmente en una dimensión
Grid    → distribución en filas y columnas

Por ejemplo, podemos utilizar Grid para organizar una página y Flexbox dentro de una cabecera o una tarjeta.

Grid y Flexbox juntos

CSS:

.cursos {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
    gap: 1.5rem;
}
.tarjeta {
    display: flex;
    flex-direction: column;
    justify-content: space-between;
}

Grid distribuye las tarjetas, mientras Flexbox organiza el contenido interno de cada tarjeta.

Errores comunes

  • confundir Grid con Flexbox y tratar de resolver todo con una sola herramienta;
  • olvidar display: grid en el contenedor;
  • usar columnas rígidas que no entran en pantallas pequeñas;
  • no aprovechar repeat();
  • no aprovechar minmax();
  • confundir líneas de Grid con columnas;
  • usar demasiada ubicación manual cuando el flujo automático ya resuelve el diseño;
  • crear layouts visuales que alteren de forma confusa el orden lógico del contenido.

Ejercicio para practicar

Partiendo de:

<section class="proyectos">
    <article>Proyecto 1</article>
    <article>Proyecto 2</article>
    <article>Proyecto 3</article>
    <article>Proyecto 4</article>
    <article>Proyecto 5</article>
    <article>Proyecto 6</article>
</section>

Intentá:

  • crear tres columnas con repeat();
  • agregar separación con gap;
  • convertir luego el diseño en responsive con auto-fit y minmax();
  • hacer que el primer proyecto ocupe dos columnas;
  • probar place-items;
  • comparar el resultado con una solución equivalente en Flexbox.

Qué aprendimos

  • display: grid;
  • grid-template-columns;
  • grid-template-rows;
  • unidad fr;
  • repeat();
  • gap;
  • minmax();
  • auto-fit y auto-fill;
  • grid-column;
  • grid-row;
  • alineación;
  • grid-template-areas;
  • diferencias entre Grid y Flexbox.

Seguí aprendiendo CSS

La guía anterior es:

Flexbox en CSS: display flex, justify-content, align-items, gap y dirección

El próximo paso será aprender a crear diseños responsive con media queries, breakpoints y técnicas para adaptar una web a celulares, tablets y escritorio.


¿Te sirvió esta guía? ☕

Si este contenido te ayudó a aprender desarrollo web, podés apoyar a Club Programador.

🇦🇷 Apoyar desde Argentina

☕ Invitame un café con Mercado Pago

🌎 Apoyar desde otro país

☕ Apoyar con PayPal

Flexbox en CSS: display flex, justify-content, align-items, gap y dirección

Aprendé Flexbox en CSS: display flex, ejes, flex-direction, justify-content, align-items, gap, wrap y propiedades flex con ejemplos prácticos.

Hasta ahora aprendimos a seleccionar elementos, trabajar con el modelo de caja y controlar tipografías, colores, fondos y unidades. El siguiente paso es aprender a distribuir y alinear elementos de forma cómoda.

Para eso existe Flexbox, uno de los sistemas de layout más utilizados en CSS.

¿Qué problema resuelve Flexbox?

Antes de Flexbox, tareas tan simples como centrar elementos verticalmente o distribuir varios bloques en una misma fila podían resultar bastante incómodas.

Flexbox permite organizar elementos dentro de un contenedor de forma flexible.

display: flex

Para activar Flexbox utilizamos:

.contenedor {
    display: flex;
}

El elemento con display: flex pasa a ser el contenedor flex. Sus hijos directos se convierten en flex items.

HTML:

<div class="contenedor">
    <div>Elemento 1</div>
    <div>Elemento 2</div>
    <div>Elemento 3</div>
</div>

CSS:

.contenedor {
    display: flex;
}

Por defecto, los elementos se colocan en una fila.

Eje principal y eje cruzado

Flexbox trabaja con dos ejes:

  • main axis: eje principal;
  • cross axis: eje cruzado.

Con la dirección por defecto:

main axis  → horizontal
cross axis → vertical

Pero esto puede cambiar según flex-direction.

flex-direction

Controla la dirección de los elementos.

.contenedor {
    display: flex;
    flex-direction: row;
}

Valores principales:

row
row-reverse
column
column-reverse

row

Los elementos se distribuyen de izquierda a derecha.

column

.contenedor {
    display: flex;
    flex-direction: column;
}

Los elementos se apilan verticalmente.

justify-content

justify-content alinea los elementos sobre el eje principal.

.contenedor {
    display: flex;
    justify-content: center;
}

Valores frecuentes:

flex-start
center
flex-end
space-between
space-around
space-evenly

space-between

.contenedor {
    display: flex;
    justify-content: space-between;
}

Distribuye el espacio libre entre los elementos.

space-around

.contenedor {
    display: flex;
    justify-content: space-around;
}

Agrega espacio alrededor de cada elemento.

space-evenly

.contenedor {
    display: flex;
    justify-content: space-evenly;
}

Distribuye espacios iguales entre elementos y bordes del contenedor.

align-items

align-items trabaja sobre el eje cruzado.

.contenedor {
    display: flex;
    align-items: center;
}

Valores comunes:

stretch
flex-start
center
flex-end
baseline

Centrado perfecto con Flexbox

Una de las técnicas más conocidas:

.contenedor {
    display: flex;
    justify-content: center;
    align-items: center;
    min-height: 100vh;
}

Esto centra el contenido tanto horizontal como verticalmente.

gap

gap permite agregar espacio entre los elementos flex.

.contenedor {
    display: flex;
    gap: 20px;
}

Es preferible a agregar márgenes manuales entre elementos cuando queremos controlar simplemente la separación.

flex-wrap

Por defecto, Flexbox intenta mantener todos los elementos en una misma línea.

Con flex-wrap podemos permitir que pasen a otra fila.

.contenedor {
    display: flex;
    flex-wrap: wrap;
}

Ejemplo con tarjetas

HTML:

<section class="cursos">

    <article class="tarjeta">
        <h2>HTML</h2>
        <p>Estructura de páginas web.</p>
    </article>

    <article class="tarjeta">
        <h2>CSS</h2>
        <p>Diseño y estilos.</p>
    </article>

    <article class="tarjeta">
        <h2>JavaScript</h2>
        <p>Interacción y comportamiento.</p>
    </article>

</section>

CSS:

.cursos {
    display: flex;
    gap: 20px;
    flex-wrap: wrap;
}
.tarjeta {
    width: 300px;
    padding: 20px;
    border: 1px solid #ccc;
    border-radius: 10px;
}

align-content

align-content trabaja cuando existen varias líneas de elementos flex.

.contenedor {
    display: flex;
    flex-wrap: wrap;
    align-content: center;
}

No debe confundirse con align-items.

align-items alinea elementos dentro de una línea; align-content distribuye las líneas completas cuando hay espacio disponible.

Propiedades de los elementos hijos

Hasta ahora vimos propiedades del contenedor. Flexbox también ofrece propiedades para los elementos hijos.

flex-grow

Define cuánto puede crecer un elemento respecto de los demás.

.item {
    flex-grow: 1;
}

Si todos tienen flex-grow: 1, compartirán el espacio disponible.

flex-shrink

Controla cuánto puede reducirse un elemento cuando no hay suficiente espacio.

.item {
    flex-shrink: 1;
}

flex-basis

Define el tamaño base de un elemento antes de distribuir el espacio restante.

.item {
    flex-basis: 250px;
}

La propiedad flex

Podemos combinar grow, shrink y basis:

.item {
    flex: 1 1 250px;
}

Esto significa:

flex-grow:   1
flex-shrink: 1
flex-basis:  250px

Un patrón muy útil para tarjetas

.tarjeta {
    flex: 1 1 280px;
}

Las tarjetas intentarán comenzar con unos 280px, podrán crecer y también reducirse cuando sea necesario.

align-self

Permite modificar la alineación de un elemento concreto.

.especial {
    align-self: flex-end;
}

Esto sobrescribe el comportamiento definido por align-items para ese elemento.

order

Flexbox también permite modificar visualmente el orden.

.destacado {
    order: -1;
}

Sin embargo, conviene usar order con cuidado porque el orden visual puede diferir del orden del HTML, lo que puede afectar la navegación y accesibilidad.

Ejemplo de menú de navegación

HTML:

<nav class="menu">

    <a href="#">Inicio</a>
    <a href="#">HTML</a>
    <a href="#">CSS</a>
    <a href="#">JavaScript</a>

</nav>

CSS:

.menu {
    display: flex;
    justify-content: center;
    gap: 2rem;
    padding: 1rem;
}
.menu a {
    color: #007bff;
    text-decoration: none;
    font-weight: bold;
}

Ejemplo de cabecera

HTML:

<header class="cabecera">

    <div class="logo">
        Club Programador
    </div>

    <nav>
        <a href="#">Inicio</a>
        <a href="#">Cursos</a>
        <a href="#">Contacto</a>
    </nav>

</header>

CSS:

.cabecera {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 1rem 2rem;
}
.cabecera nav {
    display: flex;
    gap: 1.5rem;
}

Flexbox y diseño responsive

Flexbox resulta especialmente útil para crear componentes que se adapten a distintos tamaños de pantalla.

Por ejemplo:

.cursos {
    display: flex;
    flex-wrap: wrap;
    gap: 1.5rem;
}
.tarjeta {
    flex: 1 1 280px;
}

Las tarjetas pueden acomodarse automáticamente en varias filas según el espacio disponible.

Errores comunes

  • aplicar propiedades flex al elemento equivocado;
  • confundir eje principal con eje cruzado;
  • confundir justify-content con align-items;
  • olvidar flex-wrap cuando hay muchos elementos;
  • usar márgenes para separar items cuando gap es suficiente;
  • fijar demasiados anchos rígidos;
  • usar order sin considerar accesibilidad;
  • confundir align-items con align-content.

Ejercicio para practicar

Partiendo de este HTML:

<section class="equipo">

    <article class="persona">
        <h2>Ana</h2>
        <p>Frontend</p>
    </article>

    <article class="persona">
        <h2>Luis</h2>
        <p>Backend</p>
    </article>

    <article class="persona">
        <h2>María</h2>
        <p>Diseño</p>
    </article>

</section>

Intentá:

  • mostrar las tarjetas en una fila;
  • agregar espacio con gap;
  • permitir varias filas con flex-wrap;
  • usar flex: 1 1 250px;
  • centrar el contenido de cada tarjeta;
  • probar diferentes valores de justify-content y align-items.

Qué aprendimos

  • display: flex;
  • eje principal y eje cruzado;
  • flex-direction;
  • justify-content;
  • align-items;
  • align-content;
  • gap;
  • flex-wrap;
  • flex-grow;
  • flex-shrink;
  • flex-basis;
  • flex;
  • align-self;
  • order.

Seguí aprendiendo CSS

La guía anterior es:

Tipografías, colores, fondos y unidades CSS: guía práctica

El próximo paso es aprender CSS Grid, otra herramienta fundamental para construir layouts de filas y columnas:

CSS Grid: filas, columnas, gap, fr, repeat y minmax paso a paso →


¿Te sirvió esta guía? ☕

Si este contenido te ayudó a aprender desarrollo web, podés apoyar a Club Programador.

🇦🇷 Apoyar desde Argentina

☕ Invitame un café con Mercado Pago

🌎 Apoyar desde otro país

☕ Apoyar con PayPal

Tipografías, colores, fondos y unidades CSS: guía práctica

Aprendé a trabajar con tipografías, colores, fondos y unidades CSS como px, %, em, rem, vw y vh con ejemplos prácticos.

Ya vimos cómo seleccionar elementos y cómo funciona el modelo de caja. El siguiente paso es empezar a controlar con más precisión la apariencia visual de una página.

En esta guía vamos a trabajar con tipografías, colores, fondos y las principales unidades de medida de CSS.

Tipografías en CSS

CSS permite controlar la familia tipográfica, el tamaño, el grosor, la altura de línea y otras características del texto.

font-family

La propiedad font-family define la tipografía utilizada.

body {
    font-family: Arial, Helvetica, sans-serif;
}

Es habitual definir varias opciones separadas por comas. El navegador utilizará la primera disponible.

En este ejemplo:

  • intenta usar Arial;
  • si no está disponible, intenta Helvetica;
  • si tampoco está disponible, utiliza una fuente genérica sans-serif.

Fuentes genéricas

Entre las familias genéricas más conocidas encontramos:

serif
sans-serif
monospace
cursive
fantasy

Para código fuente suele utilizarse una tipografía monoespaciada:

pre {
    font-family: Consolas, Monaco, monospace;
}

font-size

font-size controla el tamaño del texto.

p {
    font-size: 18px;
}

Sin embargo, px no es la única unidad disponible. Más adelante veremos otras opciones como rem y em.

font-weight

Controla el grosor de la tipografía.

h1 {
    font-weight: 700;
}

También podemos utilizar palabras como:

normal
bold

Valores como 400 y 700 son muy frecuentes:

400 ≈ normal
700 ≈ bold

La disponibilidad exacta depende de la fuente utilizada.

font-style

Permite aplicar, por ejemplo, texto en cursiva.

.nota {
    font-style: italic;
}

line-height

line-height controla la altura de línea.

p {
    line-height: 1.6;
}

Una altura de línea adecuada mejora mucho la legibilidad, especialmente en textos largos.

text-align

Permite alinear texto.

h1 {
    text-align: center;
}

Valores comunes:

left
center
right
justify

text-decoration

Se utiliza habitualmente para controlar subrayados.

a {
    text-decoration: none;
}

También existen valores como underline, overline y line-through.

text-transform

Permite transformar visualmente el uso de mayúsculas y minúsculas.

.titulo {
    text-transform: uppercase;
}

Otros valores útiles son:

lowercase
capitalize

letter-spacing

Controla el espacio entre caracteres.

h1 {
    letter-spacing: 2px;
}

Colores en CSS

CSS ofrece varias formas de representar colores.

Colores por nombre

p {
    color: blue;
}

Es fácil de leer, aunque ofrece menos control que otros formatos.

Colores hexadecimales

p {
    color: #007bff;
}

El formato hexadecimal comienza con # y es muy utilizado en diseño web.

RGB

RGB representa rojo, verde y azul.

p {
    color: rgb(0, 123, 255);
}

Cada componente suele utilizar valores entre 0 y 255.

RGBA

RGBA agrega un canal alfa para definir transparencia.

.caja {
    background-color: rgba(0, 123, 255, 0.25);
}

En este ejemplo, 0.25 representa una opacidad del 25%.

HSL

HSL representa:

  • Hue: tono;
  • Saturation: saturación;
  • Lightness: luminosidad.
.boton {
    background-color: hsl(211, 100%, 50%);
}

HSL puede resultar muy cómodo cuando queremos crear variaciones de un mismo color.

La propiedad color

color controla principalmente el color del texto.

body {
    color: #333333;
}

Fondos en CSS

Los fondos pueden ser colores, imágenes o combinaciones de ambos.

background-color

body {
    background-color: #f4f4f4;
}

background-image

También podemos utilizar una imagen como fondo.

.hero {
    background-image: url('fondo.jpg');
}

background-repeat

Por defecto, una imagen pequeña puede repetirse.

.hero {
    background-repeat: no-repeat;
}

background-size

cover hace que la imagen cubra el área disponible.

.hero {
    background-size: cover;
}

Otra opción frecuente es contain.

background-position

.hero {
    background-position: center;
}

Ejemplo completo de fondo

.hero {
    background-image: url('fondo.jpg');
    background-size: cover;
    background-position: center;
    background-repeat: no-repeat;
    color: white;
    padding: 80px 20px;
}

Gradientes

CSS también permite generar gradientes sin utilizar una imagen externa.

.hero {
    background: linear-gradient(135deg, #0b1220, #007bff);
}

Unidades CSS

Una de las decisiones más importantes al trabajar con CSS es elegir correctamente las unidades de medida.

No todas las unidades se comportan igual.

px

px representa píxeles CSS.

.caja {
    width: 300px;
}

Es una unidad muy utilizada porque resulta fácil de entender y controlar.

Sin embargo, un píxel CSS no siempre corresponde exactamente a un píxel físico de la pantalla. Los navegadores y dispositivos manejan escalado y densidades distintas.

%

Los porcentajes suelen depender del tamaño del elemento contenedor.

.caja {
    width: 80%;
}

Esto permite crear estructuras más flexibles.

em

em es una unidad relativa.

.boton {
    font-size: 16px;
    padding: 1em 2em;
}

En muchas propiedades, 1em toma como referencia el tamaño de fuente del propio elemento.

Por ejemplo, si el texto mide 16px:

1em = 16px
2em = 32px

rem

rem significa root em.

Se basa en el tamaño de fuente del elemento raíz, normalmente html.

html {
    font-size: 16px;
}
h1 {
    font-size: 2rem;
}

En este caso:

1rem = 16px
2rem = 32px

rem suele ser especialmente útil para mantener una escala tipográfica consistente.

em vs rem

Una forma sencilla de diferenciarlos:

em  → relativo al contexto del elemento
rem → relativo al elemento raíz

En diseños modernos es habitual utilizar rem para tipografías y espaciados generales.

vw

vw significa viewport width.

1vw representa aproximadamente el 1% del ancho del viewport.

.hero {
    width: 100vw;
}

vh

vh significa viewport height.

1vh representa aproximadamente el 1% de la altura del viewport.

.hero {
    min-height: 100vh;
}

Es frecuente utilizarlo para crear secciones que ocupen toda la altura visible.

¿Qué unidad conviene usar?

No existe una única unidad correcta para todo.

Como orientación inicial:

  • px: bordes, detalles pequeños y medidas muy específicas;
  • %: anchos relativos al contenedor;
  • rem: tipografías y espaciados escalables;
  • em: tamaños relativos al componente;
  • vw y vh: medidas relacionadas con la ventana del navegador.

Ejemplo práctico

HTML:

<section class="presentacion">

    <h1>Club Programador</h1>

    <p>
        Aprendé programación paso a paso.
    </p>

    <a href="#" class="boton">
        Ver cursos
    </a>

</section>

CSS:

body {
    margin: 0;
    font-family: Arial, Helvetica, sans-serif;
    color: #e5e7eb;
    background-color: #0b1220;
}
.presentacion {
    min-height: 100vh;
    padding: 4rem 2rem;
    text-align: center;
    background: linear-gradient(135deg, #0b1220, #1e3a8a);
}
.presentacion h1 {
    font-size: 3rem;
    line-height: 1.1;
    letter-spacing: 1px;
}
.presentacion p {
    font-size: 1.125rem;
    line-height: 1.6;
}
.boton {
    display: inline-block;
    margin-top: 1rem;
    padding: 0.8em 1.5em;
    color: white;
    background-color: #007bff;
    text-decoration: none;
    border-radius: 8px;
}

Herencia de estilos

Algunas propiedades, especialmente relacionadas con texto, pueden heredarse.

Por ejemplo:

body {
    font-family: Arial, sans-serif;
    color: #333333;
}

Muchos elementos descendientes utilizarán esa tipografía y ese color salvo que otra regla los sobrescriba.

Propiedades como margin, padding o border, en cambio, no suelen heredarse de la misma manera.

Contraste y legibilidad

Elegir colores no es solamente una cuestión estética.

El texto debe tener contraste suficiente con el fondo para que pueda leerse cómodamente.

Por ejemplo, texto gris muy claro sobre fondo blanco puede resultar difícil de leer.

También conviene evitar tamaños de fuente demasiado pequeños y alturas de línea insuficientes.

Errores comunes

  • usar demasiadas familias tipográficas diferentes;
  • elegir colores con poco contraste;
  • usar tamaños de texto excesivamente pequeños;
  • usar px para absolutamente todas las medidas sin considerar alternativas;
  • confundir em y rem;
  • usar imágenes de fondo demasiado pesadas;
  • olvidar background-size: cover cuando se busca cubrir una sección;
  • depender solamente del color para comunicar información importante.

Ejercicio para practicar

Partiendo de este HTML:

<article class="curso">

    <h2>Curso de CSS</h2>

    <p>
        Aprendé a diseñar páginas web.
    </p>

    <a href="#" class="boton">
        Comenzar
    </a>

</article>

Intentá crear un estilo que:

  • utilice una fuente sans-serif;
  • defina un color de fondo oscuro;
  • use texto claro;
  • establezca el título en 2rem;
  • use line-height para mejorar la lectura;
  • cree un botón azul;
  • use padding en em;
  • utilice un ancho relativo y un max-width.

Qué aprendimos

  • font-family;
  • font-size;
  • font-weight;
  • font-style;
  • line-height;
  • alineación y decoración del texto;
  • HEX, RGB, RGBA y HSL;
  • fondos e imágenes;
  • gradientes;
  • px, %, em, rem, vw y vh;
  • herencia;
  • contraste y legibilidad.

Seguí aprendiendo CSS

La guía anterior es:

Modelo de caja en CSS: width, height, margin, padding, border y box-sizing

El próximo paso es empezar a trabajar con Flexbox, una de las herramientas más importantes de CSS para distribuir y alinear elementos:

Flexbox en CSS: display flex, justify-content, align-items, gap y dirección →


¿Te sirvió esta guía? ☕

Si este contenido te ayudó a aprender desarrollo web, podés apoyar a Club Programador.

🇦🇷 Apoyar desde Argentina

☕ Invitame un café con Mercado Pago

🌎 Apoyar desde otro país

☕ Apoyar con PayPal

Modelo de caja en CSS: width, height, margin, padding, border y box-sizing

Aprendé el modelo de caja en CSS: width, height, margin, padding, border, border-box, content-box, max-width y overflow con ejemplos prácticos.

Después de aprender a seleccionar elementos con CSS, el siguiente concepto fundamental es entender cómo ocupa espacio cada elemento dentro de una página.

CSS representa cada elemento como una caja. Esa caja está formada por contenido, espacio interior, borde y espacio exterior.

¿Qué es el modelo de caja?

El modelo de caja —o box model— describe cómo se calcula el tamaño y el espacio que ocupa un elemento HTML.

margin
└── border
    └── padding
        └── contenido

Las cuatro partes principales son:

  • content: el contenido del elemento;
  • padding: espacio interior entre contenido y borde;
  • border: borde que rodea el elemento;
  • margin: espacio exterior que separa el elemento de otros.

Un ejemplo simple

<div class="tarjeta">
    Curso de CSS
</div>

CSS:

.tarjeta {
    width: 300px;
    padding: 20px;
    border: 2px solid #007bff;
    margin: 30px;
}

width

La propiedad width define el ancho.

.tarjeta {
    width: 300px;
}

Sin embargo, el ancho final puede depender de padding, border y de la propiedad box-sizing.

height

height define la altura.

.caja {
    height: 200px;
}

En muchos casos conviene permitir que la altura se adapte automáticamente al contenido en lugar de fijarla.

padding: espacio interior

El padding crea espacio entre el contenido y el borde.

.tarjeta {
    padding: 20px;
}

También podemos definir cada lado por separado:

.tarjeta {
    padding-top: 10px;
    padding-right: 20px;
    padding-bottom: 10px;
    padding-left: 20px;
}

Forma abreviada de padding

Con un valor:

.tarjeta {
    padding: 20px;
}

Aplica 20 píxeles a los cuatro lados.

Con dos valores:

.tarjeta {
    padding: 10px 20px;
}

El primero corresponde arriba y abajo; el segundo, izquierda y derecha.

Con cuatro valores:

.tarjeta {
    padding: 10px 20px 30px 40px;
}

El orden es:

arriba → derecha → abajo → izquierda

margin: espacio exterior

margin controla el espacio alrededor del elemento.

.tarjeta {
    margin: 20px;
}

También existe:

margin-top
margin-right
margin-bottom
margin-left

Margin automático

Una técnica clásica para centrar horizontalmente un elemento con ancho definido es:

.contenedor {
    width: 800px;
    margin: 0 auto;
}

auto distribuye automáticamente el espacio horizontal disponible.

border

El borde rodea el contenido y el padding.

.tarjeta {
    border: 1px solid #cccccc;
}

Esta propiedad combina:

  • grosor;
  • tipo de línea;
  • color.

También podemos escribirlas por separado:

.tarjeta {
    border-width: 2px;
    border-style: solid;
    border-color: #007bff;
}

border-radius

Permite redondear las esquinas.

.tarjeta {
    border-radius: 12px;
}

¿Cuánto mide realmente una caja?

Supongamos esta regla:

.caja {
    width: 300px;
    padding: 20px;
    border: 5px solid #000;
}

Con el comportamiento tradicional de CSS, width: 300px representa solamente el contenido.

El ancho real será:

300px contenido
+ 40px padding
+ 10px border
= 350px

content-box

El valor por defecto de box-sizing suele ser content-box.

.caja {
    box-sizing: content-box;
}

En este modo, width y height se aplican al contenido y luego se agregan padding y borde.

border-box

Con border-box, el ancho declarado incluye contenido, padding y borde.

.caja {
    width: 300px;
    padding: 20px;
    border: 5px solid #000;
    box-sizing: border-box;
}

En este caso, la caja completa mantiene un ancho total de 300px.

¿Por qué se usa tanto border-box?

Porque vuelve mucho más predecible el cálculo de tamaños.

Por eso es muy habitual comenzar una hoja de estilos con:

* {
    box-sizing: border-box;
}

Una versión aún más completa es:

*, *::before, *::after {
    box-sizing: border-box;
}

Ejemplo práctico con tarjetas

HTML:

<section class="cursos">

    <article class="tarjeta">
        <h2>HTML</h2>
        <p>Estructura de páginas web.</p>
    </article>

    <article class="tarjeta">
        <h2>CSS</h2>
        <p>Estilos y diseño visual.</p>
    </article>

</section>

CSS:

* {
    box-sizing: border-box;
}
.tarjeta {
    width: 300px;
    padding: 20px;
    margin: 20px;
    border: 1px solid #cccccc;
    border-radius: 10px;
}

Margin y padding no son lo mismo

Una forma simple de recordarlo:

padding = espacio dentro de la caja
margin  = espacio fuera de la caja

Si queremos separar el texto del borde, usamos padding.

Si queremos separar una tarjeta de otra, usamos margin.

Width en porcentaje

También podemos trabajar con medidas relativas.

.tarjeta {
    width: 80%;
}

En este caso, el ancho depende del elemento contenedor.

max-width

Una propiedad muy útil es max-width.

.contenedor {
    width: 90%;
    max-width: 1000px;
    margin: 0 auto;
}

Así el elemento puede adaptarse a pantallas pequeñas sin crecer indefinidamente en pantallas grandes.

min-width y min-height

También podemos establecer tamaños mínimos.

.tarjeta {
    min-width: 250px;
    min-height: 150px;
}

Overflow

¿Qué pasa si el contenido no entra en una caja con tamaño limitado?

CSS ofrece la propiedad overflow.

.caja {
    height: 100px;
    overflow: auto;
}

Con auto, el navegador puede agregar barras de desplazamiento cuando sean necesarias.

Errores comunes

  • confundir margin con padding;
  • olvidar que el borde también ocupa espacio;
  • no tener en cuenta box-sizing;
  • fijar alturas innecesariamente;
  • usar anchos rígidos demasiado grandes;
  • no considerar cómo se verá una caja en pantallas pequeñas;
  • usar muchos márgenes para resolver problemas que deberían tratarse con layout.

Ejercicio para practicar

Partiendo de este HTML:

<article class="perfil">

    <h2>Ana López</h2>

    <p>
        Estudiante de desarrollo web.
    </p>

</article>

Creá una regla CSS que:

  • tenga un ancho de 350px;
  • use border-box;
  • agregue 25px de padding;
  • tenga un borde azul;
  • redondee las esquinas;
  • agregue margen exterior;
  • y luego compará qué ocurre si cambiás border-box por content-box.

Qué aprendimos

  • modelo de caja;
  • contenido;
  • width y height;
  • padding;
  • margin;
  • border;
  • border-radius;
  • content-box;
  • border-box;
  • max-width y tamaños mínimos;
  • overflow.

Seguí aprendiendo CSS

La guía anterior es:

Selectores CSS: etiquetas, clases, ID, descendientes y combinadores

El próximo paso es trabajar con tipografías, colores, fondos y unidades CSS para empezar a controlar con más precisión la identidad visual de nuestras páginas:

Tipografías, colores, fondos y unidades CSS: guía práctica →


¿Te sirvió esta guía? ☕

Si este contenido te ayudó a aprender desarrollo web, podés apoyar a Club Programador.

🇦🇷 Apoyar desde Argentina

☕ Invitame un café con Mercado Pago

🌎 Apoyar desde otro país

☕ Apoyar con PayPal

Selectores CSS: etiquetas, clases, ID, descendientes y combinadores

Aprendé selectores CSS desde cero: etiquetas, clases, ID, selector universal, descendientes, hijos directos, hermanos, atributos y especificidad.

En la guía anterior aprendimos qué es CSS, cómo conectarlo con HTML y cómo escribir nuestras primeras reglas. Ahora vamos a profundizar en una de las partes más importantes: los selectores.

Los selectores permiten indicar con precisión qué elementos HTML queremos modificar.

¿Qué es un selector CSS?

Un selector identifica uno o varios elementos del documento.

Por ejemplo:

p {
    color: #333;
    font-size: 18px;
}

En esta regla, p es el selector. Significa que el estilo se aplicará a todos los párrafos.

Selector por etiqueta

Es el selector más simple.

<h2>Título de sección</h2>
<p>Primer párrafo</p>
<p>Segundo párrafo</p>

CSS:

p {
    color: blue;
}

Todos los elementos p serán azules.

Selector por clase

Las clases son una de las herramientas más utilizadas en CSS porque permiten reutilizar estilos.

<p class="destacado">
    Texto importante
</p>

<p class="destacado">
    Otro texto importante
</p>

CSS:

.destacado {
    color: #007bff;
    font-weight: bold;
}

El punto . indica que estamos seleccionando una clase.

Selector por ID

<h1 id="titulo-principal">
    Club Programador
</h1>

CSS:

#titulo-principal {
    color: #007bff;
}

El símbolo # indica un selector por id.

Class vs ID

Una diferencia práctica:

  • class: se puede reutilizar en varios elementos;
  • id: debería identificar un elemento único dentro de la página.

Para estilos, normalmente conviene utilizar clases porque son más reutilizables y flexibles.

Selector universal

El selector universal se representa con *.

* {
    box-sizing: border-box;
}

Esta regla afecta a todos los elementos.

Más adelante veremos por qué box-sizing: border-box es tan habitual cuando trabajamos con el modelo de caja.

Agrupar selectores

Podemos aplicar las mismas reglas a varios selectores separándolos con comas.

h1, h2, h3 {
    font-family: Arial, sans-serif;
}

Así evitamos repetir código.

Selector descendiente

Permite seleccionar elementos que están dentro de otros.

<section class="noticias">
    <h2>Noticias</h2>
    <p>Primera noticia</p>
</section>

<p>Texto fuera de la sección</p>

CSS:

.noticias p {
    color: green;
}

Solo los párrafos dentro de .noticias serán verdes.

Hijo directo: >

El combinador > selecciona elementos que son hijos directos.

<div class="contenedor">
    <p>Hijo directo</p>

    <section>
        <p>Descendiente, pero no hijo directo</p>
    </section>
</div>

CSS:

.contenedor > p {
    color: red;
}

Solo el primer párrafo será afectado.

Hermano adyacente: +

El combinador + selecciona el elemento inmediatamente siguiente.

<h2>Título</h2>
<p>Primer párrafo</p>
<p>Segundo párrafo</p>

CSS:

h2 + p {
    font-weight: bold;
}

Solo el primer párrafo después del h2 será afectado.

Hermanos generales: ~

El combinador ~ selecciona hermanos posteriores del mismo nivel.

h2 ~ p {
    color: #555;
}

Selectores de atributos

Podemos seleccionar elementos según la presencia o el valor de un atributo.

<input type="text">
<input type="email">
<input type="password">

CSS:

input[type="email"] {
    border: 2px solid #007bff;
}

Solo el campo de tipo email tendrá ese borde.

Seleccionar por presencia de atributo

input[required] {
    background-color: #fffbe6;
}

Esta regla afecta a todos los inputs que tengan el atributo required.

Combinar selectores

Los selectores pueden combinarse.

<p class="mensaje importante">
    Atención
</p>

CSS:

p.importante {
    color: red;
}

Esto selecciona párrafos que además tengan la clase importante.

Más de una clase

<div class="tarjeta destacada">
    Contenido
</div>

CSS:

.tarjeta.destacada {
    border: 2px solid #007bff;
}

Introducción a la especificidad

¿Qué ocurre si varias reglas intentan cambiar la misma propiedad?

Por ejemplo:

<p id="mensaje" class="destacado">
    Hola
</p>

Y CSS:

p {
    color: blue;
}

.destacado {
    color: green;
}

#mensaje {
    color: red;
}

En este ejemplo, el selector por ID tiene mayor especificidad y el texto terminará siendo rojo.

Como introducción, podemos pensar este orden aproximado:

etiqueta  <  clase  <  id

Más adelante profundizaremos en cómo se calcula realmente la especificidad.

El orden también importa

Si dos reglas tienen la misma especificidad, normalmente prevalece la que aparece más abajo.

p {
    color: blue;
}

p {
    color: green;
}

En este caso, los párrafos serán verdes.

Ejemplo práctico

HTML:

<main class="contenido">

    <article class="tarjeta destacada">

        <h2>Curso de HTML</h2>

        <p>
            Aprendé HTML desde cero.
        </p>

        <a href="#" class="boton">
            Ver curso
        </a>

    </article>

    <article class="tarjeta">

        <h2>Curso de CSS</h2>

        <p>
            Aprendé a aplicar estilos.
        </p>

        <a href="#" class="boton">
            Ver curso
        </a>

    </article>

</main>

CSS:

.contenido {
    font-family: Arial, sans-serif;
}
.tarjeta {
    border: 1px solid #ccc;
    padding: 20px;
    margin-bottom: 20px;
}
.tarjeta.destacada {
    border: 2px solid #007bff;
}
.tarjeta h2 {
    color: #007bff;
}
.boton {
    text-decoration: none;
    font-weight: bold;
}

Errores comunes

  • olvidar el punto al seleccionar una clase;
  • olvidar el # al seleccionar un id;
  • usar el mismo id en varios elementos;
  • crear selectores demasiado largos y difíciles de mantener;
  • abusar de IDs para estilos;
  • confundir descendiente con hijo directo;
  • no entender por qué una regla pierde frente a otra por especificidad;
  • repetir reglas que podrían agruparse.

Ejercicio para practicar

Partiendo de este HTML:

<section class="cursos">

    <article class="curso destacado">
        <h2>HTML</h2>
        <p>Curso inicial</p>
    </article>

    <article class="curso">
        <h2>CSS</h2>
        <p>Curso de estilos</p>
    </article>

</section>

Intentá crear reglas para:

  • cambiar el color de todos los h2 dentro de .cursos;
  • agregar un borde a todos los elementos con clase curso;
  • aplicar un estilo diferente solo a .destacado;
  • modificar únicamente los párrafos dentro de los cursos.

Qué aprendimos

  • selector por etiqueta;
  • selector por clase;
  • selector por ID;
  • selector universal;
  • agrupación de selectores;
  • descendientes;
  • hijos directos;
  • hermanos adyacentes y generales;
  • selectores de atributos;
  • combinación de clases;
  • introducción a la especificidad;
  • importancia del orden de las reglas.

Seguí aprendiendo CSS

La guía anterior es:

Introducción a CSS: qué es, cómo funciona y cómo aplicar estilos a una página HTML

El próximo paso es estudiar uno de los conceptos fundamentales de CSS: el modelo de caja:

Modelo de caja en CSS: width, height, margin, padding, border y box-sizing →


¿Te sirvió esta guía? ☕

Si este contenido te ayudó a aprender desarrollo web, podés apoyar a Club Programador.

🇦🇷 Apoyar desde Argentina

☕ Invitame un café con Mercado Pago

🌎 Apoyar desde otro país

☕ Apoyar con PayPal

Introducción a CSS: qué es, cómo funciona y cómo aplicar estilos a una página HTML

Aprendé CSS desde cero: qué es, cómo se conecta con HTML, selectores, colores, tipografías, márgenes, padding, bordes y primeros estilos.

Después de aprender a estructurar una página con HTML, el siguiente paso es controlar cómo se ve. Para eso utilizamos CSS.

Importante: CSS no es un lenguaje de programación. Es un lenguaje de estilos que utilizamos para definir la presentación visual de un documento HTML.

¿Qué significa CSS?

CSS significa Cascading Style Sheets, es decir, hojas de estilo en cascada.

Su función principal es definir cómo se presenta el contenido de una página:

  • colores;
  • tipografías;
  • tamaños;
  • espacios;
  • bordes;
  • fondos;
  • alineación;
  • columnas;
  • disposición de elementos;
  • diseño adaptable a distintos dispositivos.

HTML y CSS trabajan juntos

Podemos pensar la relación de esta manera:

HTML       -> estructura y contenido
CSS        -> estilos y presentación
JavaScript -> comportamiento e interacción

HTML indica qué contenido existe. CSS define cómo se ve.

Por ejemplo, HTML puede crear un título:

<h1>Club Programador</h1>

Y CSS puede definir su color y tamaño:

h1 {
    color: blue;
    font-size: 40px;
}

La sintaxis básica de CSS

Una regla CSS suele tener esta estructura:

selector {
    propiedad: valor;
}

Por ejemplo:

p {
    color: green;
    font-size: 18px;
}

En este caso:

  • p es el selector;
  • color y font-size son propiedades;
  • green y 18px son valores.

¿Qué es un selector?

El selector indica qué elementos HTML queremos modificar.

Si escribimos:

h2 {
    color: red;
}

todos los elementos h2 afectados por esa regla se mostrarán con ese color.

Tres formas de aplicar CSS

CSS puede aplicarse de tres maneras principales.

1. CSS inline

El estilo se escribe directamente dentro del elemento HTML:

<p style="color: blue;">
    Texto azul
</p>

Puede ser útil para una prueba puntual, pero no es la mejor opción para organizar un sitio completo.

2. CSS interno

Podemos escribir reglas dentro de una etiqueta style en el head:

<head>

    <style>

        p {
            color: blue;
        }

    </style>

</head>

3. CSS externo

La forma más habitual para proyectos reales es utilizar un archivo independiente.

Por ejemplo:

mi-sitio/
|
|-- index.html
|-- styles.css

Dentro de styles.css podemos escribir:

body {
    background-color: #f5f5f5;
    font-family: Arial, sans-serif;
}

Y desde HTML lo vinculamos así:

<link rel="stylesheet" href="styles.css">

¿Dónde colocar el link de CSS?

La referencia al archivo CSS se coloca normalmente dentro de head:

<!DOCTYPE html>
<html lang="es">

<head>

    <meta charset="UTF-8">

    <meta
        name="viewport"
        content="width=device-width, initial-scale=1.0"
    >

    <title>Mi página</title>

    <link
        rel="stylesheet"
        href="styles.css"
    >

</head>

<body>

    <h1>Hola mundo</h1>

</body>

</html>

Primer ejemplo completo

Supongamos que tenemos este archivo index.html:

<!DOCTYPE html>
<html lang="es">

<head>

    <meta charset="UTF-8">

    <meta
        name="viewport"
        content="width=device-width, initial-scale=1.0"
    >

    <title>Mi primera página con CSS</title>

    <link
        rel="stylesheet"
        href="styles.css"
    >

</head>

<body>

    <h1>Club Programador</h1>

    <p>
        Estoy aprendiendo CSS.
    </p>

</body>

</html>

Y este archivo styles.css:

body {
    background-color: #f4f4f4;
    font-family: Arial, sans-serif;
}
h1 {
    color: #007bff;
    font-size: 40px;
}
p {
    color: #333;
    font-size: 18px;
}

Al abrir index.html en el navegador, veremos que HTML mantiene la estructura y CSS modifica su apariencia.

Selectores de etiqueta

El selector más básico utiliza el nombre de una etiqueta HTML.

p {
    color: #333;
}

Esta regla afecta a los párrafos.

Selectores por class

Una clase permite aplicar el mismo estilo a varios elementos.

HTML:

<p class="destacado">
    Primer texto
</p>

<p class="destacado">
    Segundo texto
</p>

CSS:

.destacado {
    color: #007bff;
    font-weight: bold;
}

Las clases se escriben en CSS comenzando con un punto.

Selectores por id

También podemos seleccionar un elemento por su id.

HTML:

<h1 id="titulo-principal">
    Club Programador
</h1>

CSS:

#titulo-principal {
    color: #007bff;
}

Los identificadores se escriben en CSS comenzando con #.

¿Class o id?

Como regla inicial:

  • class: para estilos que pueden reutilizarse;
  • id: para identificar un elemento concreto.

En CSS moderno, para estilos reutilizables es habitual trabajar principalmente con clases.

Colores

CSS permite definir colores de distintas formas.

Por nombre

h1 {
    color: blue;
}

Hexadecimal

h1 {
    color: #007bff;
}

RGB

h1 {
    color: rgb(0, 123, 255);
}

Color de fondo

body {
    background-color: #f5f5f5;
}

Tipografías

Podemos elegir una familia tipográfica:

body {
    font-family: Arial, Helvetica, sans-serif;
}

Tamaño del texto

p {
    font-size: 18px;
}

px significa píxeles, aunque más adelante veremos otras unidades como rem, em, %, vw y vh.

Negrita

h1 {
    font-weight: bold;
}

Alineación del texto

h1 {
    text-align: center;
}

Bordes

.tarjeta {
    border: 1px solid #cccccc;
}

Border radius

Podemos redondear las esquinas:

.tarjeta {
    border-radius: 10px;
}

Margin y padding

Dos propiedades fundamentales son margin y padding.

.tarjeta {
    margin: 20px;
    padding: 20px;
}

Podemos pensarlo así:

margin
    espacio exterior

border
    borde

padding
    espacio interior

contenido

Más adelante veremos esto con detalle cuando estudiemos el modelo de caja.

Transformemos una sección HTML

Supongamos que tenemos:

<section class="presentacion">

    <h1>Juan Pérez</h1>

    <p>
        Estudiante de programación
    </p>

</section>

Podemos aplicar:

.presentacion {
    background-color: #0b1220;
    color: white;
    padding: 40px;
    text-align: center;
    border-radius: 12px;
}

Con unas pocas propiedades, una estructura HTML muy simple empieza a transformarse visualmente.

CSS no cambia el significado del HTML

CSS puede hacer que un elemento se vea completamente diferente, pero su significado semántico sigue estando definido por HTML.

Por ejemplo, un h1 sigue siendo el encabezado principal aunque CSS cambie su tamaño, color o tipografía.

Por eso conviene construir primero un HTML correcto y después aplicar estilos.

¿Qué significa “en cascada”?

La palabra Cascading hace referencia a que pueden existir varias reglas que intenten aplicar estilos al mismo elemento.

El navegador debe decidir cuál prevalece teniendo en cuenta factores como:

  • el origen de la regla;
  • la especificidad del selector;
  • el orden en que aparecen las reglas;
  • algunas reglas especiales que veremos más adelante.

No hace falta dominarlo todavía. Lo importante es entender que CSS tiene un sistema para resolver conflictos entre estilos.

Errores comunes al comenzar con CSS

  • olvidar el punto y coma al separar declaraciones;
  • olvidar los dos puntos entre propiedad y valor;
  • escribir incorrectamente el selector;
  • olvidar enlazar styles.css desde HTML;
  • usar una ruta incorrecta en href;
  • confundir class con id;
  • intentar resolver la estructura del contenido únicamente con CSS;
  • abusar de estilos inline cuando el proyecto empieza a crecer.

Qué aprendimos

En esta primera guía de CSS vimos:

  • qué es CSS;
  • por qué no es un lenguaje de programación;
  • cómo se relaciona con HTML;
  • la sintaxis selector-propiedad-valor;
  • CSS inline, interno y externo;
  • cómo crear styles.css;
  • cómo enlazarlo con HTML;
  • selectores de etiqueta, clase e id;
  • colores;
  • tipografías;
  • tamaños;
  • fondos;
  • bordes;
  • margin y padding.

De HTML a CSS

Si venís siguiendo la ruta de desarrollo web, el paso anterior fue:

Proyecto final HTML: crear una página web completa desde cero

El siguiente paso es profundizar en los selectores CSS para aprender a elegir con precisión qué elementos queremos modificar:

Selectores CSS: etiquetas, clases, ID, descendientes y combinadores →

Después continuaremos con modelo de caja, tipografías, Flexbox, Grid y diseño responsive.


¿Te sirvió esta guía? ☕

Si este contenido te ayudó a aprender desarrollo web, podés apoyar a Club Programador. Cada aporte ayuda a mantener el sitio online y a seguir publicando material gratuito.

🇦🇷 Apoyar desde Argentina

☕ Invitame un café con Mercado Pago

🌎 Apoyar desde otro país

☕ Apoyar con PayPal