WhatsApp

  

Split Landing Page

Qué es, cómo funciona y código listo

¿Qué es?

Una “split landing page” es una portada con dos mitades a pantalla completa. Al hover sobre una mitad, esta crece y atrae la atención; al salir, todo vuelve al 50/50.

Conceptos clave que aprenderás

  • Layout con Flexbox para dividir el viewport en dos paneles.

  • Transiciones y pseudo-clases para animar el cambio de anchos.

  • Clases dinámicas con JS (.hover-left / .hover-right) para controlar estados. (Patrón usado en múltiples implementaciones públicas del reto.)

Código (3 archivos separados)

1) index.html

<!DOCTYPE html>
<html lang="es">
<head>
  <meta charset="utf-8" />
  <meta name="viewport" content="width=device-width,initial-scale=1" />
  <title>Split Landing Page</title>
  <link rel="stylesheet" href="style.css" />
</head>
<body>
  <main class="split">
    <section class="pane left">
      <div class="overlay">
        <h1>Opción A</h1>
        <a class="btn" href="#a">Explorar</a>
      </div>
    </section>
    <section class="pane right">
      <div class="overlay">
        <h1>Opción B</h1>
        <a class="btn" href="#b">Explorar</a>
      </div>
    </section>
  </main>
  <script src="script.js"></script>
</body>
</html>


2) Style.css

* { box-sizing: border-box; }
:root {
  --speed: 600ms;
  --radius: 24px;
  --gap: 8px;
}
html, body {
  height: 100%;
  margin: 0;
  font-family: system-ui, -apple-system, Segoe UI, Roboto, Arial, sans-serif;
  background: #0f1115;
  color: #f5f7fa;
}
/* Contenedor “split” a pantalla completa */
.split {
  display: flex;
  height: 100vh;
  gap: var(--gap);
  padding: var(--gap);
}
/* Panel base */
.pane {
  flex: 1 1 50%;
  position: relative;
  border-radius: var(--radius);
  overflow: hidden;
  transition: flex-basis var(--speed) ease, transform var(--speed) ease;
  background-size: cover;
  background-position: center;
}
/* Imágenes de ejemplo (cámbialas por las tuyas) */
.left  { background-image: url("https://picsum.photos/id/1018/1600/900"); }
.right { background-image: url("https://picsum.photos/id/1025/1600/900"); }
/* Capa oscura y contenido centrado */
.overlay {
  position: absolute; inset: 0;
  background: linear-gradient(180deg, rgba(0,0,0,.25), rgba(0,0,0,.55));
  display: grid; place-content: center; text-align: center;
  padding: 24px;
}
h1 { margin: 0 0 16px; font-size: clamp(28px, 4vw, 56px); }
.btn {
  display: inline-block;
  padding: 12px 20px;
  border-radius: 999px;
  border: 2px solid rgba(255,255,255,.85);
  color: #fff; text-decoration: none;
  transition: transform 180ms ease, background-color 180ms ease, border-color 180ms ease;
  backdrop-filter: blur(2px);
}
.btn:hover { transform: translateY(-2px); background: rgba(255,255,255,.08); border-color: #fff; }
/* Estados de hover activados por clases JS */
.split.hover-left  .left  { flex-basis: 75%; }
.split.hover-left  .right { flex-basis: 25%; }
.split.hover-right .right { flex-basis: 75%; }
.split.hover-right .left  { flex-basis: 25%; }
/* Sutileza: zoom leve del panel activo */
.split.hover-left  .left,
.split.hover-right .right { transform: scale(1.02); }
/* Responsive (táctiles): apilar en vertical si el alto es limitado */
@media (max-width: 760px) {
  .split { flex-direction: column; }
}


3) Script.js

const split = document.querySelector('.split');
const left  = document.querySelector('.left');
const right = document.querySelector('.right');
function onEnterLeft()  { split.classList.add('hover-left');  }
function onLeaveLeft()  { split.classList.remove('hover-left'); }
function onEnterRight() { split.classList.add('hover-right'); }
function onLeaveRight() { split.classList.remove('hover-right'); }
left.addEventListener('mouseenter', onEnterLeft);
left.addEventListener('mouseleave', onLeaveLeft);
right.addEventListener('mouseenter', onEnterRight);
right.addEventListener('mouseleave', onLeaveRight);
/* Soporte básico táctil: al tocar, expandir esa mitad */
left.addEventListener('touchstart',  onEnterLeft,  { passive: true });
right.addEventListener('touchstart', onEnterRight, { passive: true });
document.addEventListener('touchend', () => {
  split.classList.remove('hover-left', 'hover-right');
}, { passive: true });


El patrón de añadir/quitar clases en mouseenter/mouseleave (o touch) es el enfoque más común para este mini-proyecto y clones, porque deja la animación en manos del CSS.


Personaliza en 30 segundos

  • Cambia las fotos: reemplaza las URLs de background-image por tus propias imágenes (CDN o ruta local).

  • Texto y botón: edita los <h1> y .btn.

  • Velocidad y proporciones: ajusta --speed y los flex-basis: 75% / 25% en los estados .hover-left / .hover-right.

Accesibilidad & UX rápidos

  • Mantén contraste alto en el overlay para legibilidad.

  • Añade :focus-visible a .btn si tendrá navegación por teclado.

  • En móviles el layout se apila (media query), y el toque activa la expansión un instante para evitar “estado pegado”.


Ejemplo

Finalmente tu implementación debería verse similar a esta 





 


Split Landing Page
Paris Minero 20 octubre, 2025
Compartir
Iniciar sesión dejar un comentario

  
Blurry Loading
efecto de desenfoque mientras carga (vanilla HTML/CSS/JS)