Estilizando la página de empleos
Ahora que hemos aprendido sobre clases, pseudo-clases, especificidad y selectores, es momento de poner todo en práctica estilizando nuestra página de empleos (empleos.html).
El objetivo
Vamos a crear una sección de listado de empleos con:
- Un contenedor con borde redondeado
- Artículos (ofertas de empleo) separados por bordes
- Layout flexible con información organizada
- El último artículo sin borde inferior (usando
:last-child)
La estructura HTML
<div class="jobs-listings">
<article class="job-listing-card">
<div>
<h3>Ingeniero de Software</h3>
<small>Tech Solutions Inc. | Remoto</small>
<p>
Buscamos un ingeniero de software con experiencia en desarrollo web y conocimientos en
JavaScript, React y Node.js. El candidato ideal debe ser capaz de trabajar en equipo y tener
buenas habilidades de comunicación.
</p>
</div>
<button class="button-apply-job" id="boton-importante">Aplicar</button>
</article>
<article class="job-listing-card">
<div>
<h3>Analista de Datos</h3>
<small>Data Driven Co. | Ciudad de México</small>
<p>
Estamos buscando un analista de datos con experiencia en el manejo de grandes conjuntos de
datos y herramientas de visualización. Se requiere conocimiento en SQL, Python y R.
</p>
</div>
<button class="button-apply-job">Aplicar</button>
</article>
<article class="job-listing-card">
<div>
<h3>Desarrollador de Aplicaciones Móviles</h3>
<small>Mobile Apps Ltd. | Guadalajara</small>
<p>
Buscamos un desarrollador de aplicaciones móviles con experiencia en iOS y/o Android. El
candidato debe tener conocimientos en Swift, Kotlin y el desarrollo de interfaces de
usuario.
</p>
</div>
<button class="button-apply-job">Aplicar</button>
</article>
<article class="job-listing-card">
<div>
<h3>Ingeniero de DevOps</h3>
<small>Cloud Services SA | Remoto</small>
<p>
Estamos buscando un ingeniero de DevOps con experiencia en la gestión de infraestructuras en
la nube, automatización de procesos y herramientas de integración continua. Se requiere
conocimiento en AWS, Azure o GCP.
</p>
</div>
<button class="button-apply-job">Aplicar</button>
</article>
</div>
Los estilos CSS
.jobs-listings {
border: 1px solid rgba(255, 255, 255, 0.3);
border-radius: 1rem;
article {
background: none;
box-shadow: none;
border-radius: 0;
border-bottom: 1px solid rgba(255, 255, 255, 0.3);
margin: 0;
display: flex;
align-items: start;
gap: 1rem;
small {
font-size: 0.875rem;
opacity: 0.75;
}
p {
margin-top: 0.5rem;
}
&:last-child {
border-bottom: none;
}
}
}
Desglosando el CSS
1. El contenedor principal
.jobs-listings {
border: 1px solid rgba(255, 255, 255, 0.3);
border-radius: 1rem;
}
border: Borde sutil usando color blanco con transparencia (.3= 30% de opacidad)border-radius: 1rem: Esquinas redondeadas (1rem = 16px aproximadamente)
2. Los artículos individuales (.job-listing-card)
.jobs-listings {
article {
background: none;
box-shadow: none;
border-radius: 0;
border-bottom: 1px solid rgba(255, 255, 255, 0.3);
margin: 0;
}
}
Estos estilos sobrescriben posibles estilos previos que pudieran tener los <article>:
background: none: Sin fondobox-shadow: none: Sin sombraborder-radius: 0: Sin esquinas redondeadasborder-bottom: Línea separadora entre empleosmargin: 0: Sin margen exterior
3. Layout flexible
.jobs-listings {
article {
display: flex;
align-items: start;
gap: 1rem;
}
}
display: flex: Convierte el artículo en contenedor flexiblealign-items: start: Alinea los elementos al inicio (arriba)gap: 1rem: Espacio entre los elementos (contenido y botón)
Esto coloca el contenido de la oferta a la izquierda y el botón “Aplicar” a la derecha.
4. Estilizando elementos internos
.jobs-listings {
article {
small {
font-size: 0.875rem;
opacity: 0.75;
}
p {
margin-top: 0.5rem;
}
}
}
small: Texto más pequeño (0.875rem ≈ 14px) y con transparencia (75% opaco)p: Añade separación superior para el párrafo de descripción
La pseudo-clase :last-child
La parte más interesante es esta:
.jobs-listings {
article {
&:last-child {
border-bottom: none;
}
}
}
¿Qué hace :last-child?
La pseudo-clase :last-child selecciona un elemento solo si es el último hijo de su contenedor padre.
Problema sin :last-child
Sin usar :last-child, todos los artículos tendrían el borde inferior:
┌─────────────────────────────┐
│ Artículo 1 │
├─────────────────────────────┤ ← Borde
│ Artículo 2 │
├─────────────────────────────┤ ← Borde
│ Artículo 3 │
├─────────────────────────────┤ ← Borde innecesario
└─────────────────────────────┘
Solución con :last-child
Con :last-child, el último artículo no tiene borde inferior:
┌─────────────────────────────┐
│ Artículo 1 │
├─────────────────────────────┤ ← Borde
│ Artículo 2 │
├─────────────────────────────┤ ← Borde
│ Artículo 3 │ ← Sin borde
└─────────────────────────────┘
Pseudo-clases relacionadas
CSS tiene otras pseudo-clases similares a :last-child:
:first-child
Selecciona el primer hijo:
article {
&:first-child {
border-top: 3px solid blue; /* Borde especial en el primero */
}
}
:nth-child()
Selecciona elementos según su posición:
/* Elementos pares */
article:nth-child(even) {
background: #f5f5f5;
}
/* Elementos impares */
article:nth-child(odd) {
background: white;
}
/* Tercer elemento */
article:nth-child(3) {
font-weight: bold;
}
/* Cada 3 elementos */
article:nth-child(3n) {
border-left: 3px solid blue;
}
:only-child
Selecciona un elemento solo si es el único hijo:
article:only-child {
/* Se aplica si hay un solo artículo */
border: 2px solid gold;
}
El repaso final para mover las manitas
:last-child: Selecciona el último hijo de un contenedor- Útil para: Eliminar bordes, márgenes o estilos innecesarios en el último elemento
- Familia de pseudo-clases:
:first-child,:nth-child(),:only-child - CSS Nesting: Permite organizar estilos de forma jerárquica
- Flexbox: Ideal para crear layouts de listados