Diseño de página web con HTML, CSS y JavaScript: una agencia responsive paso a paso

Crea el diseño de una página web de agencia con HTML, CSS y JavaScript: preloader, menú que cambia con el scroll y galería con filtro. Plantilla gratis.

Este es un diseño de página web con HTML, CSS y JavaScript completo: la web de una agencia con preloader, menú que cambia al hacer scroll, secciones de equipo y servicios, y una galería de trabajos que se filtra por categoría. Todo es responsive y lo haces desde cero.

El curso tiene 4 capítulos. Aquí tienes el primero, el código de cada paso explicado y la plantilla completa para descargarla gratis.

Al finalizar este tutorial lograrás:

  • Resultado: la página web de una agencia, adaptable a móviles, lista para usarla como portafolio o para tu empresa.
  • Tecnologías: HTML, CSS (variables, Flexbox, object-fit) y JavaScript con un poco de jQuery.
  • Nivel: principiante con nociones básicas de HTML y CSS.
  • Ir directo al código fuente

Qué vas a construir

Una página de una sola pantalla para una agencia de desarrollo web: cabecera con imagen y degradado, equipo, servicios, trabajos con filtro y pie de página con redes sociales. Cada parte practica una técnica distinta:

Parte de la páginaTécnica que aprendes
Pantalla de cargaPreloader de Loading.io que desaparece con jQuery
CabeceraDegradado sobre una imagen y efecto parallax con background-attachment: fixed
MenúCambia de transparente a sólido al hacer scroll, con JavaScript
Equipo y trabajosTarjetas con Flexbox y object-fit: cover
Galería de trabajosFiltro por categoría con jQuery
MóvilMenú hamburguesa que se cierra al tocar fuera
Diseño de página web con HTML, CSS y JavaScript: agencia AlexCG Design con equipo, servicios y galería de trabajos

El curso completo son 4 videos:

  1. Capítulo 1: el HTML de toda la página (37 min)
  2. Capítulo 2: el diseño con CSS (50 min)
  3. Capítulo 3: el menú con JavaScript y la versión móvil (41 min)
  4. Capítulo 4: el filtro de la galería y el scroll a cada sección (19 min)

Qué necesitas

  • Un editor de código, por ejemplo Visual Studio Code.
  • Los iconos de los servicios, de Flaticon (PNG blanco de 64 px), y los de redes sociales, de Font Awesome.
  • jQuery para el filtro y el scroll suave, y un preloader de Loading.io.
  • Conocimientos básicos de HTML y CSS. El JavaScript se explica desde cero.

Paso a paso

Prepara el proyecto y los recursos

Crea una carpeta con index.html, estilos.css, una carpeta img para las fotos y una js para los scripts. En el <head> enlaza tu hoja de estilos y la hoja de Font Awesome desde su CDN, que es lo que dibuja los iconos de YouTube, Facebook y GitHub del pie. Los scripts van al final del <body>, con jQuery primero porque filtro.js lo necesita.

<link rel="stylesheet" href="estilos.css">
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.3.1/css/all.css" integrity="sha384-mzrmE5qonljUremFsqc01SB46JvROS7bZs3IO2EmfFsd15uHvIt+Y8vEf7N7fWAU"
    crossorigin="anonymous">

<script src="js/jquery.js"></script>
<script src="js/main.js"></script>
<script src="js/filtro.js"></script>

Escribe el menú y la cabecera

El menú vive dentro del <header>: un contenedor con el logo, los cinco enlaces y el icono de menú para móvil. Cada enlace tiene un id propio porque en el último paso JavaScript los usará para hacer scroll a su sección. El icono de hamburguesa es el carácter &#9776;, así no hace falta otra fuente ni otra imagen.

<nav id="nav" class="nav1">
    <div class="contenedor-nav">
        <div class="logo">
            <img src="img/logo.png" alt="">
        </div>
        <div class="enlaces" id="enlaces">
            <a href="#" id="enlace-inicio" class="btn-header">Inicio</a>
            <a href="#" id="enlace-equipo" class="btn-header">Equipo</a>
            <a href="#" id="enlace-servicio" class="btn-header">Servicios</a>
            <a href="#" id="enlace-trabajo" class="btn-header">Trabajos</a>
            <a href="#" id="enlace-contacto" class="btn-header">Contacto</a>
        </div>
        <div class="icono" id="open">
            <span>&#9776;</span>
        </div>
    </div>
</nav>

Crea las secciones de equipo, servicios y trabajos

Las tres secciones repiten el mismo patrón: un título, un subtítulo con la clase after y una fila de cajas. En la galería, cada trabajo lleva su categoría como clase (programacion, diseño o marketing) y cada botón del filtro la guarda en data-nombre. Esa coincidencia es lo que después usa el filtro.

<div class="botones-work">
    <ul>
        <li class="filter active" data-nombre='todos'>Todos</li>
        <li class="filter" data-nombre='diseño'>Diseño</li>
        <li class="filter" data-nombre='programacion'>Programacion</li>
        <li class="filter" data-nombre='marketing'>Marketing</li>
    </ul>
</div>
<div class="galeria-work">
    <div class="cont-work programacion">
        <div class="img-work">
            <img src="img/programacion1.jpeg" alt="">
        </div>
        <div class="textos-work">
            <h4>Programacion</h4>
        </div>
    </div>
</div>

Define las variables de CSS

Antes de dar estilo a nada, el capítulo 2 guarda colores, tamaños y espacios en variables dentro de :root. Al estar en la raíz, todos los elementos pueden usarlas. La ventaja se ve en el responsive: para reducir los márgenes en móvil solo cambias --margenes, no cada sección.

:root{
  --color1: rgb(219,144,.5);
  --color2: rgba(23, 180, 83, 0.877);
  --color3: rgba(11,194,211, 0.623);
  --fondo: #f2f2f2;
  --titulos: 33px;
  --margenes: 60px;
  --espacios: 10px;
  --espacios-contenido:45px;
}

Dale a la cabecera un degradado con efecto parallax

El fondo de la cabecera son dos capas en un solo background: primero un degradado semitransparente de naranja a verde y azul, y debajo la foto. Con background-attachment: fixed la imagen se queda quieta mientras el contenido sube, y ese es el efecto parallax.

header{
  width: 100%;
  height:600px;
  background: linear-gradient(to bottom,
  rgba(211,135,20, .6),
  rgba(29,241,171, .6),
  rgba(7,109,150, .45)
  ), url(img/fondo.jpg);
  background-attachment: fixed;
  background-position: center;
  background-size: cover;
}

Ordena las tarjetas con Flexbox y object-fit

Las tarjetas del equipo están en una fila Flexbox con flex-wrap, así que bajan de línea cuando no caben. Cada tarjeta mide 400 px de alto: el 80 % para la foto y el 20 % para el texto. object-fit: cover hace que la foto llene su caja sin deformarse, recortando lo que sobra.

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

.content-card{
  width: 31%;
  box-shadow: 0 0 6px 0 rgba(0,0,0,.5);
  overflow: hidden;
  height:400px;
}

.content-card img{
  width: 100%;
  height: 100%;
  object-fit: cover;
}

Cambia el menú al hacer scroll

El menú tiene dos estados en CSS: .nav1, transparente y de 80 px, y .nav2, con fondo y de 100 px. En el capítulo 3, JavaScript lee cuánto has bajado (window.pageYOffset) y a partir de 300 px cambia una clase por la otra. La función también se ejecuta al cargar la página, por si alguien la recarga a mitad del scroll.

function menus(){
    let Desplazamiento_Actual = window.pageYOffset;

    if(Desplazamiento_Actual <= 300){
        nav.classList.remove('nav2');
        nav.className = ('nav1');
        nav.style.transition = '1s';
        menu.style.top = '80px';
        abrir.style.color = '#fff';
    }else{
        nav.classList.remove('nav1');
        nav.className = ('nav2');
        nav.style.transition = '1s';
        menu.style.top = '100px';
        abrir.style.color = '#000';
    }
}

Haz el menú hamburguesa para móviles

Por debajo de 700 px los enlaces pasan a ser un panel fijo con width: 0, es decir, escondido. Al tocar el icono, apertura() le da un 70 % del ancho de la pantalla, y al volver a tocarlo lo cierra. Un tercer evento cierra el menú si tocas en cualquier otra parte de la página.

@media screen and (max-width: 700px){
  .enlaces{
    position: fixed;
    top:80px;
    background: #2c3e50;
    left: 0;
    height: 100%;
    transition: 1s;
    width: 0;
    overflow: hidden;
  }
}
function apertura(){
    if(cerrado){
        menu.style.width = '70vw';
        cerrado = false;
    }else{
        menu.style.width = '0%';
        menu.style.overflow = 'hidden';
        cerrado = true;
    }
}

Muestra un preloader mientras carga la página

El <body> empieza con la clase hidden (sin scroll) y una capa negra a pantalla completa con la animación de Loading.io encima. Cuando la página termina de cargar, jQuery desvanece la capa y quita la clase.

.centrado{
  position: fixed;
  width: 100vw;
  height: 100vh;
  background: #000;
  z-index: 100;
  display: flex;
  justify-content: center;
  align-items: center;
}
window.addEventListener('load', function(){
    $('#onload').fadeOut();
    $('body').removeClass('hidden');
    menus();
});

Filtra la galería de trabajos con jQuery

En el capítulo 4, al hacer clic en un botón, este se marca como activo y sus hermanos pierden la clase. Después se lee su data-nombre: con «todos» se muestran todas las cajas, y con una categoría se ocultan las que no la tienen y se muestran las que sí.

$('.filter').click(function () {
    $(this).addClass('active').siblings().removeClass('active');
    let valor = $(this).attr('data-nombre');
    if (valor == 'todos') {
        $('.cont-work').show('1000');
    } else {
        $('.cont-work').not('.' + valor).hide('1000');
        $('.cont-work').filter('.' + valor).show('1000');
    }
});

Lleva cada enlace a su sección con scroll suave

Cada enlace del menú evita su comportamiento normal y anima el scroll hasta la posición de su sección. Se restan 100 px porque es lo que mide el menú fijo: sin eso, el título de la sección quedaría tapado.

let equipo = $('#equipo').offset().top;

$('#enlace-equipo').on('click', function(e){
    e.preventDefault();
    $('html, body').animate({
        scrollTop: equipo -100
    },600);
});

Consejo

El curso es de 2018. Hoy puedes conseguir el mismo scroll sin jQuery: pon scroll-behavior: smooth en el html, href="#equipo" en el enlace y scroll-margin-top: 100px en la sección. Y si quieres controlar el tamaño de los subtítulos, añade --subtitulos a :root: .contenedor p la usa, pero no está definida.

Código fuente

La plantilla tiene el proyecto completo: index.html, estilos.css, main.js, filtro.js, jQuery, todas las imágenes y los iconos de Flaticon. Es libre de derechos de autor: úsala como quieras.

Patrocinador oficial del curso

Hostinger es el patrocinador oficial del curso. Si quieres publicar esta página en internet con tu propio dominio, entra con el enlace de AlexCG Design.

Preguntas frecuentes

¿Puedo usar esta plantilla en mis proyectos?

Sí. La plantilla es libre de derechos de autor: descárgala, cambia los textos, las fotos y los colores, y úsala como base para tu portafolio, tu empresa o la página de un cliente. Los iconos de Flaticon sí piden atribuir al autor si no tienes licencia, como explico en el capítulo 1.

¿Necesito jQuery para hacer esta página web?

Solo para dos cosas: el filtro de la galería y el scroll suave del menú, que se usan para ahorrar tiempo. El menú que cambia al hacer scroll y el menú hamburguesa están hechos con JavaScript puro. Si prefieres no usar jQuery, el scroll suave hoy se resuelve con CSS (mira el consejo después de los pasos).

¿Cómo cambio los colores del diseño?

Desde las variables de :root. Los títulos, las líneas bajo los subtítulos y los botones del filtro usan --color1: si cambias su valor, cambian todos a la vez. El archivo trae otros dos colores, verde y azul, preparados en --color2 y --color3.

Más proyectos

Curso

Domina HTML5 y CSS3

Mi curso para diseñar páginas web modernas desde cero, como esta.

4 comentarios

  1. :root{
    –color1: rgb(219,144,.5);
    –color2: rgba(23, 180, 83, 0.877);
    –color3: rgba(11,194,211, 0.623);
    –fondo: #f2f2f2;
    –titulos: 33px;
    –margenes: 60px;
    –espacios: 10px;
    –espacios-contenido:45px;
    }

    * {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
    }

    body {
    font-family: ‘open sans’;
    background: var(–fondo);
    }

    img{
    vertical-align: top;
    }

    /* Preloader */
    .hidden{
    overflow: hidden;
    }

    .centrado{
    position: fixed;
    width: 100vw;
    height: 100vh;
    background: #000;
    z-index: 100;
    display: flex;
    justify-content: center;
    align-items: center;
    }
    .lds-facebook {
    display: inline-block;
    position: relative;
    width: 64px;
    height: 64px;
    }

    .lds-facebook div {
    display: inline-block;
    position: absolute;
    left: 6px;
    width: 13px;
    background: #cef;
    animation: lds-facebook 1.2s cubic-bezier(0, 0.5, 0.5, 1) infinite;
    }

    .lds-facebook div:nth-child(1) {
    left: 6px;
    animation-delay: -0.24s;
    }

    .lds-facebook div:nth-child(2) {
    left: 26px;
    animation-delay: -0.12s;
    }

    .lds-facebook div:nth-child(3) {
    left: 45px;
    animation-delay: 0;
    }

    @keyframes lds-facebook {
    0% {
    top: 6px;
    height: 51px;
    }

    50%,
    100% {
    top: 19px;
    height: 26px;
    }
    }

    /* Header */

    header{
    width: 100%;
    height:600px;
    background: linear-gradient(to bottom,
    rgba(211,135,20, .6),
    rgba(29,241,171, .6),
    rgba(7,109,150, .45)
    ), url(img/fondo.jpg);
    background-attachment: fixed;
    background-position: center;
    background-size: cover;
    }

    nav{
    width: 100%;
    position: fixed;
    box-shadow: 0 0 10px 0 rgba(0,0,0,.5)
    }

    .nav1{
    background: transparent;
    height: 80px;
    color:#fff;
    }

    .nav2{
    background: var(–fondo);
    height:100px;
    color:#000;
    }

    .contenedor-nav{
    display: flex;
    margin: auto;
    width: 90%;
    justify-content: space-between;
    align-items: center;
    max-width:1000px;
    height:inherit;
    overflow: hidden;
    }

    nav .enlaces a{
    display: inline-block;
    padding: 5px 0;
    margin-right: 17px;
    font-size: 17px;
    font-weight: 300;
    text-decoration: none;
    border-bottom: 3px solid transparent;
    color: inherit;
    }

    nav .enlaces a:hover{
    border-bottom: 3px solid #1498a4;
    transition: 0.6s;
    }

    .logo, .logo img{ height:80px;}

    .icono{
    display:none;
    font-size: 24px;
    padding: 23.5px 20px;
    }

    .textos{
    width: 100%;
    height: 100%;
    display:flex;
    justify-content: center;
    flex-direction: column;
    align-items: center;
    color:#fff;
    overflow: hidden;
    text-align: center;
    }

    .textos>h1{font-size:80px;;}

    .textos>h2{font-size: 30px; font-weight: 300;}

    /* Main */

    .contenedor{
    margin:auto;
    padding: var(–margenes) 0;
    width: 90%;
    max-width: 1000px;
    text-align: center;
    overflow: hidden;
    }

    .contenedor h3{
    font-size: var(–titulos);
    color: var(–color1);
    margin-bottom: var(–espacios);
    }

    .contenedor p{
    font-size: var(–subtitulos);
    font-weight: 300;
    color: var(–color1);
    }

    .after::after{
    content:»;
    display: block;
    margin: auto;
    margin-top: var(–espacios);
    width: 100px;
    height: 2px;
    background: var(–color1);
    margin-bottom: var(–espacios-contenido);
    }

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

    .content-card{
    width: 31%;
    box-shadow: 0 0 6px 0 rgba(0,0,0,.5);
    overflow: hidden;
    height:400px;
    }

    .people{
    height: 80%;
    }

    .content-card img{
    width: 100%;
    height: 100%;
    object-fit: cover;
    }

    .texto-team{
    height: 20%;
    width: 100%;
    padding: var(–espacios) 0;
    }

    .about{
    background: url(img/teclado.jpg);
    height: auto;
    }

    .servicios{
    display: flex;
    color:#fff;
    justify-content: space-between;
    margin: auto;
    flex-wrap: wrap;
    }
    .caja-servicios{
    width: 30%;
    margin: auto;
    text-align: center;
    }
    .caja-servicios>h4{
    margin-bottom: var(–espacios);
    }

    .caja-servicios>p{
    text-align: center;
    }

    .botones-work{
    overflow: hidden;
    }

    .botones-work li{
    display: inline-block;
    text-align: center;
    margin-left: var(–espacios);
    margin-bottom: var(–espacios-contenido);
    padding: 6px 12px;
    border: 1px solid var(–color1);
    list-style: none;
    color: var(–color1);
    }

    .botones-work li:hover{
    background: var(–color1);
    color:#fff;
    cursor: pointer;
    }

    .botones-work .active{
    background: var(–color1);
    color:#fff;
    }

    .galeria-work{
    display:flex;
    flex-wrap: wrap;
    justify-content: space-around;
    }

    .cont-work{
    width: 31%;
    box-shadow: 0 0 6px 0 rgba(0,0,0,.5);
    height:300px;
    overflow: hidden;
    margin-bottom: var(–espacios-contenido);
    }

    .img-work{
    height: 90%;
    width: 100%;
    }

    .img-work img{
    height: 100%;
    width: 100%;
    object-fit: cover;
    }

    .textos-work{
    height: 10%;
    }

    .textos-work h4{
    line-height: 30px;
    font-weight: 300;
    }

    /* Footer */

    footer{background:url(img/teclado.jpg);}

    .marca-logo{
    width: 40%;
    margin: auto;
    margin-bottom: var(–espacios);
    }
    .marca-logo img{
    width: 100%;
    }
    .iconos{
    display: flex;
    margin: auto;
    justify-content: space-around;
    width: 100%;
    }
    .fab{
    font-size:60px;
    color: #FFF;
    margin-bottom: var(–espacios);
    display: inline-block;
    }

    footer p{
    margin-top:var(–espacios);
    }

    @media screen and (max-width: 700px){
    .nav2{
    color: #fff;
    }

    .icono{
    display:block;
    cursor: pointer;
    }

    .enlaces{
    position: fixed;
    top:80px;
    background: #2c3e50;
    left: 0;
    height: 100%;
    transition: 1s;
    width: 0;
    overflow: hidden;
    }

    .enlaces a{
    display: block;
    width: 100%;
    height: 50px;
    padding: 20px;
    text-align: center;
    background: #34495e;
    color:#fff;
    }

    .textos>h1{font-size: 70px;}
    .textos>h2{font-size:35px;}

    .content-card{
    width: 48%;
    margin-bottom:var(–margenes);
    }

    :root{
    –margenes: 30px;
    }
    }

    @media screen and (max-width: 500px){
    :root{
    –espacios-contenido: 25px;
    }

    .content-card{
    width: 90%;
    }

    .caja-servicios{
    width: 90%;
    margin-bottom: var(–margenes);
    }

    .cont-work{
    width: 85%;
    }

    .marca-logo{
    width: 80%;
    }

    .iconos{
    margin: auto;
    }
    }

    este fue el css que le puse a la pagina web
    y al momento de que se lo puse
    desaparecio el scrollbar

Los comentarios están cerrados.