Rompiendo las reglas del UX/UI
Web

Efecto divisor (Split) — Demo + Código listo para copiar

Arrastra horizontalmente para revelar el contenido. Accesible por teclado (← →), responsive y sin dependencias.

Rompiendo las reglas del UX/UI
Web

Cómo funciona

  1. Capa izquierda (.split-left) cambia su width entre 10% y 90% según la posición del puntero.
  2. Divisor (.split-divider) acompaña visualmente el corte.
  3. Micro-interacciones: parallax sutil y halo siguiendo el cursor.
  4. Accesibilidad: control por teclado con flechas (atributos ARIA de “slider”).
HTML
<section class="split-stage" role="slider" aria-label="Control deslizante de división de pantalla" aria-valuemin="10" aria-valuemax="90" aria-valuenow="60" tabindex="0">
  <div class="split-right" aria-hidden="true"></div>
  <div class="split-left" aria-hidden="true" id="splitLeft"></div>
  <div class="split-divider" aria-hidden="true"></div>

  <div class="side side--left" aria-hidden="true">
    <div class="side__inner">
      <h3 class="title title--left">
        Rompiendo las reglas del UX/UI<br />
        <span class="fancy">ElSalto</span>
      </h3>
    </div>
  </div>

  <div class="side side--right">
    <div class="side__inner">
      <h3 class="title title--right">
        Rompiendo las reglas del UX/UI<br />
        <span class="fancy">Web</span>
      </h3>
    </div>
  </div>

  <div class="split-hint" aria-hidden="true">← Arrastra para explorar →</div>
</section>
CSS
:root{
  --brand:#a0e234;
  --bg:#0b0b0f;
  --fg:#e7e7ea;
  --muted:#a3a3ad;
  --divider-size: 3px;
  --halo-size: 240px;
  --radius: 16px;
}

.split-stage{
  position: relative;
  isolation: isolate;
  width: min(1100px, 96vw);
  aspect-ratio: 16/9;
  margin-inline: auto;
  border-radius: var(--radius);
  overflow: clip;
  background: radial-gradient(1200px 1200px at var(--cursor-x, 50%) var(--cursor-y, 50%),
              color-mix(in oklab, var(--brand) 16%, transparent) 0%,
              transparent 45%),
              linear-gradient(180deg, #0d0d12, #0a0a0c);
  box-shadow:
    0 10px 30px rgba(0,0,0,.35),
    inset 0 0 0 1px rgba(255,255,255,.06);
}

.split-left,
.split-right{
  position:absolute; inset:0;
  transition: width .18s ease;
  will-change: width;
}

.split-left{
  width:60%;
  background:
    linear-gradient(180deg, color-mix(in oklab, var(--brand) 14%, transparent), transparent 70%),
    radial-gradient(1000px 900px at 10% 10%, rgba(160,226,52,.12), transparent 60%),
    linear-gradient(135deg, #12131a, #0c0e12 55%, #0a0b0e);
  clip-path: inset(0 0 0 0 round var(--radius) 0 0 var(--radius));
}

.split-right{
  background:
    linear-gradient(180deg, rgba(255,255,255,.04), transparent 60%),
    linear-gradient(135deg, #0b0c10, #0e1016 60%, #0a0b0e);
}

.split-divider{
  position:absolute; top:0; bottom:0; left:60%;
  width:var(--divider-size);
  background: linear-gradient(180deg, #ffffff, #ffffff) padding-box,
              linear-gradient(180deg, color-mix(in oklab, var(--brand) 55%, #ffffff), transparent) border-box;
  border-left:1px solid color-mix(in oklab, var(--brand) 65%, #ffffff);
  border-right:1px solid rgba(255,255,255,.06);
  box-shadow:
    0 0 0 3px rgba(255,255,255,.03),
    0 0 30px color-mix(in oklab, var(--brand) 35%, transparent);
  pointer-events:none;
}

.side{
  position:absolute; inset:0; display:grid; place-items:center; padding:clamp(16px, 4vw, 40px);
}
.side--left{ color: var(--fg); opacity: var(--left-opacity, 1); transform: translateX(calc(var(--left-shift, 0) * 1rem)); }
.side--right{ color: var(--fg); opacity: var(--right-opacity, 1); transform: translateX(calc(var(--right-shift, 0) * 1rem)); }

.side__inner{ text-align:center; filter: drop-shadow(0 6px 24px rgba(0,0,0,.35)); }

.title{
  font-family: ui-sans-serif, system-ui, "Segoe UI", Roboto, Inter, "Helvetica Neue", Arial;
  font-weight: 800; line-height: 1.05;
  letter-spacing: -0.02em;
  font-size: clamp(28px, 5.5vw, 56px);
}

.title--left .fancy{ color: var(--brand); }

.title--right .fancy{
  background: linear-gradient(90deg, var(--brand), #d7ff86 60%, #fff);
  -webkit-background-clip: text; background-clip: text; color: transparent;
}

.split-stage::after{
  content:""; position:absolute; inset:0;
  background:
    radial-gradient(var(--halo-size) var(--halo-size) at var(--cursor-x, 50%) var(--cursor-y, 50%),
      color-mix(in oklab, var(--brand) 18%, transparent), transparent 60%);
  mix-blend-mode: soft-light;
  pointer-events:none;
}

.split-hint{
  position:absolute; bottom:10px; left:50%; translate:-50% 0;
  font-size: 12px; letter-spacing:.02em;
  color: var(--muted);
  background: rgba(255,255,255,.06);
  border:1px solid rgba(255,255,255,.08);
  padding:6px 10px; border-radius: 999px;
  backdrop-filter: blur(8px);
}

.split-stage:focus{
  outline: 2px solid var(--brand);
  outline-offset: 4px;
}

@media (max-width: 768px){
  .split-stage{ aspect-ratio: 4/5; }
  .split-hint{ font-size: 11px; bottom:8px; }
}

@media (prefers-reduced-motion: reduce){
  .split-left, .side--left, .side--right{ transition: none !important; }
}
JS
(() => {
  const left      = document.getElementById('splitLeft');
  const stage     = document.querySelector('.split-stage');
  const divider   = document.querySelector('.split-divider');
  let dragging = false;
  let rafId = null;
  let pctCache = 60;

  const clamp = (n, a, b)=> Math.min(Math.max(n, a), b);
  const px = (n)=> `${n}px`;

  const setPct = (pct) => {
    pctCache = pct;
    left.style.width = pct + '%';
    if (divider) divider.style.left = pct + '%';
    const normalizedPct = (pct - 50) / 50;
    stage?.style.setProperty('--left-opacity', 1 - Math.abs(normalizedPct) * 0.3);
    stage?.style.setProperty('--right-opacity', 1 - Math.abs(normalizedPct) * 0.3);
    stage?.style.setProperty('--left-shift',  normalizedPct * 0.5);
    stage?.style.setProperty('--right-shift', -normalizedPct * 0.5);
    stage?.setAttribute('aria-valuenow', Math.round(pct));
  };

  const handlePointer = (clientX, clientY)=> {
    stage?.style.setProperty('--cursor-x', px(clientX));
    stage?.style.setProperty('--cursor-y', px(clientY));
    const pct = clamp((clientX / stage.clientWidth) * 100, 10, 90);
    setPct(pct);
  };

  const onPointerDown = (e)=>{
    dragging = true;
    stage.setPointerCapture?.(e.pointerId);
  };
  const onPointerUp = (e)=>{
    dragging = false;
    stage.releasePointerCapture?.(e.pointerId);
  };
  const onPointerMove = (e)=>{
    const rect = stage.getBoundingClientRect();
    const x = e.clientX - rect.left;
    const y = e.clientY - rect.top;

    if (!dragging && e.pointerType === 'mouse') {
      if (rafId) cancelAnimationFrame(rafId);
      rafId = requestAnimationFrame(()=> handlePointer(x, y));
      return;
    }
    if (!dragging) return;
    if (rafId) cancelAnimationFrame(rafId);
    rafId = requestAnimationFrame(()=> handlePointer(x, y));
  };

  // Teclado
  stage?.addEventListener('keydown', (e) => {
    const step = (e.shiftKey ? 10 : 5);
    let newVal = pctCache;
    if (e.key === 'ArrowLeft')  newVal = Math.max(10, pctCache - step);
    if (e.key === 'ArrowRight') newVal = Math.min(90, pctCache + step);
    if (newVal !== pctCache){
      e.preventDefault();
      setPct(newVal);
    }
  });

  // Eventos
  stage?.addEventListener('pointerdown', onPointerDown);
  window.addEventListener('pointerup', onPointerUp);
  stage?.addEventListener('pointermove', onPointerMove, { passive: true });
  window.addEventListener('resize', ()=> setPct(pctCache));

  // Init
  window.addEventListener('load', ()=> setPct(60), { once:true });
})();

¿Quieres usar imágenes? Sustituye los gradients de .split-left y .split-right por background-image: url(...) y añade background-size: cover; background-position: center;.

ChatKit de OpenAI: Revolucionando la Comunicación Digital

Agentes de IA con LangChain

Agentes de IA con LangChain: arquitectura, seguridad y resultados

Efecto de estrellas detrás de tu ratón

¿Te fascina el cielo estrellado? 🌌🌠 Explora este proyecto "Star Trails with Options" y personaliza la magia del firmamento. 💫🔧
Slider CSS Moderno UI/UX Impactante para Landing Pages

Slider responsivo solo HTML y CSS

Slider totalmente personalizado que hemos creado utilizando solo HTML y CSS.

NBA LEGENDS

Leyendas de la NBA: Quiénes son los GOATs de la Historia

Cómo mejorar la experiencia de usuario (UX) con un diseño web profesional

UI/UX en acción: claves para optimizar tu web y aumentar conversiones