Crear una página web con scroll horizontal nunca había sido tan fácil. Hoy te cuento cómo hacerlo con la ayuda de la inteligencia artificial y Claude.ai.
1. Configuración inicial.
Le pedí a Claude.ai que diseñara una página con cinco secciones, desplazamiento horizontal y, por supuesto, que fuera responsive. El resultado inicial: un diseño creado como un componente de React.
Si no quieres desarrollarlo en React, también puedes pedirle que genere el proyecto utilizando HTML, CSS y JavaScript. Esto te dará un archivo listo para ejecutar en cualquier navegador, sin necesidad de complicarte con frameworks.
Probé la web en el móvil y el menú no se adaptaba bien. Volví a Claude.ai y ajusté los estilos para solucionar el problema. Añadió reglas CSS específicas para tamaños de pantalla más pequeños, y voilà, ¡todo listo!
Al inspeccionar la web, comprobé que el menú ya se adaptaba perfectamente aunque como siempre, necesita pequeños retoques, como ajustar la altura del contenedor en móviles.
¿El veredicto? Una página funcional, estética y adaptable a cualquier dispositivo, hecha en tiempo récord. ¿Te atreves a probarlo tú también?
Abajo te dejo el video, el código y el archivo resultante!
<!DOCTYPE html>
<html lang="es">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Sitio con Desplazamiento Horizontal</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
overflow: hidden;
font-family: Arial, sans-serif;
}
nav {
position: fixed;
top: 0;
left: 0;
right: 0;
z-index: 50;
background: white;
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
padding: 1rem;
}
.nav-container {
max-width: 1200px;
margin: 0 auto;
display: flex;
justify-content: center;
gap: 1rem;
}
.menu-toggle {
display: none;
background: none;
border: none;
font-size: 1.5rem;
cursor: pointer;
padding: 0.5rem;
position: absolute;
right: 1rem;
top: 0.5rem;
}
nav button:not(.menu-toggle) {
padding: 0.5rem 1rem;
border: none;
border-radius: 0.5rem;
cursor: pointer;
transition: all 0.3s;
background: none;
white-space: nowrap;
}
nav button:hover:not(.menu-toggle) {
background: #f3f4f6;
}
nav button.active {
background: #1f2937;
color: white;
}
.container {
display: flex;
height: 100vh;
transition: transform 0.5s ease;
}
section {
flex: 0 0 100%;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
color: white;
text-align: center;
padding: 2rem;
}
.content {
max-width: 600px;
}
h2 {
font-size: 2.5rem;
margin-bottom: 1rem;
}
p {
font-size: 1.25rem;
}
.nav-button {
position: fixed;
top: 50%;
transform: translateY(-50%);
background: white;
border: none;
border-radius: 50%;
width: 40px;
height: 40px;
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
}
.nav-button:disabled {
opacity: 0.5;
cursor: not-allowed;
}
#prevBtn {
left: 1rem;
}
#nextBtn {
right: 1rem;
}
.indicators {
position: fixed;
bottom: 2rem;
left: 50%;
transform: translateX(-50%);
display: flex;
gap: 0.5rem;
}
.indicator {
width: 12px;
height: 12px;
border-radius: 50%;
background: rgba(255, 255, 255, 0.5);
border: none;
cursor: pointer;
}
.indicator.active {
background: white;
}
@media (max-width: 768px) {
.menu-toggle {
display: block;
}
.nav-container {
display: none;
flex-direction: column;
width: 100%;
position: absolute;
top: 100%;
left: 0;
background: white;
padding: 0.5rem;
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
}
.nav-container.show {
display: flex;
}
nav button:not(.menu-toggle) {
width: 100%;
text-align: left;
padding: 0.75rem 1rem;
}
h2 {
font-size: 1.75rem;
}
p {
font-size: 1rem;
}
.nav-button {
width: 32px;
height: 32px;
}
#prevBtn {
left: 0.5rem;
}
#nextBtn {
right: 0.5rem;
}
}
</style>
</head>
<body>
<nav id="navigation">
<button class="menu-toggle" id="menuToggle">☰</button>
<div class="nav-container" id="navContainer">
<button class="active" data-index="0">Inicio</button>
<button data-index="1">Servicios</button>
<button data-index="2">Productos</button>
<button data-index="3">Sobre Nosotros</button>
<button data-index="4">Contacto</button>
</div>
</nav>
<div class="container" id="container">
<section style="background-color: #3b82f6;">
<div class="content">
<h2>Inicio</h2>
<p>Bienvenidos a nuestra página</p>
</div>
</section>
<section style="background-color: #22c55e;">
<div class="content">
<h2>Servicios</h2>
<p>Nuestros servicios profesionales</p>
</div>
</section>
<section style="background-color: #eab308;">
<div class="content">
<h2>Productos</h2>
<p>Explore nuestra gama de productos</p>
</div>
</section>
<section style="background-color: #a855f7;">
<div class="content">
<h2>Sobre Nosotros</h2>
<p>Conozca más sobre nuestra empresa</p>
</div>
</section>
<section style="background-color: #ef4444;">
<div class="content">
<h2>Contacto</h2>
<p>Póngase en contacto con nosotros</p>
</div>
</section>
</div>
<button id="prevBtn" class="nav-button" disabled><</button>
<button id="nextBtn" class="nav-button">></button>
<div class="indicators" id="indicators"></div>
<script>
let currentSection = 0;
const totalSections = 5;
const container = document.getElementById('container');
const prevBtn = document.getElementById('prevBtn');
const nextBtn = document.getElementById('nextBtn');
const navButtons = document.querySelectorAll('.nav-container button');
const indicators = document.getElementById('indicators');
const menuToggle = document.getElementById('menuToggle');
const navContainer = document.getElementById('navContainer');
// Toggle menú móvil
menuToggle.addEventListener('click', () => {
navContainer.classList.toggle('show');
});
// Cerrar menú al seleccionar una sección
document.addEventListener('click', (e) => {
if (!e.target.closest('nav')) {
navContainer.classList.remove('show');
}
});
// Crear indicadores
for (let i = 0; i < totalSections; i++) {
const indicator = document.createElement('button');
indicator.classList.add('indicator');
if (i === 0) indicator.classList.add('active');
indicator.addEventListener('click', () => goToSection(i));
indicators.appendChild(indicator);
}
function updateButtons() {
prevBtn.disabled = currentSection === 0;
nextBtn.disabled = currentSection === totalSections - 1;
// Actualizar navegación superior
navButtons.forEach((button, index) => {
button.classList.toggle('active', index === currentSection);
});
// Actualizar indicadores
document.querySelectorAll('.indicator').forEach((indicator, index) => {
indicator.classList.toggle('active', index === currentSection);
});
}
function goToSection(index) {
currentSection = index;
container.style.transform = `translateX(-${currentSection * 100}%)`;
updateButtons();
navContainer.classList.remove('show'); // Cerrar menú al navegar
}
// Event Listeners
prevBtn.addEventListener('click', () => {
if (currentSection > 0) {
goToSection(currentSection - 1);
}
});
nextBtn.addEventListener('click', () => {
if (currentSection < totalSections - 1) {
goToSection(currentSection + 1);
}
});
navButtons.forEach((button, index) => {
button.addEventListener('click', () => goToSection(index));
});
// Soporte para gestos táctiles
let touchStartX = 0;
let touchEndX = 0;
document.addEventListener('touchstart', e => {
touchStartX = e.changedTouches[0].screenX;
});
document.addEventListener('touchend', e => {
touchEndX = e.changedTouches[0].screenX;
handleSwipe();
});
function handleSwipe() {
const swipeThreshold = 50;
const diff = touchStartX - touchEndX;
if (Math.abs(diff) > swipeThreshold) {
if (diff > 0 && currentSection < totalSections - 1) {
// Deslizar a la izquierda
goToSection(currentSection + 1);
} else if (diff < 0 && currentSection > 0) {
// Deslizar a la derecha
goToSection(currentSection - 1);
}
}
}
// Soporte para teclas de flecha
document.addEventListener('keydown', e => {
if (e.key === 'ArrowLeft' && currentSection > 0) {
goToSection(currentSection - 1);
} else if (e.key === 'ArrowRight' && currentSection < totalSections - 1) {
goToSection(currentSection + 1);
}
});
// Soporte para la rueda del ratón
let isScrolling = false;
document.addEventListener('wheel', (e) => {
if (!isScrolling) {
isScrolling = true;
// Determinar la dirección del scroll
if (e.deltaY > 0 && currentSection < totalSections - 1) {
// Scroll hacia abajo/derecha
goToSection(currentSection + 1);
} else if (e.deltaY < 0 && currentSection > 0) {
// Scroll hacia arriba/izquierda
goToSection(currentSection - 1);
}
// Prevenir scroll múltiple
setTimeout(() => {
isScrolling = false;
}, 800); // Tiempo de espera para el siguiente scroll
}
// Prevenir el scroll vertical por defecto
e.preventDefault();
}, { passive: false });
</script>
</body>
</html>
Lenguaje del código: HTML, XML (xml)