Original article: How to Build Your Own Developer Portfolio Website with HTML, CSS, and JavaScript

En estos días todos necesitan tener un sitio web y aplicaciones web. Así que si trabajas como desarrollador web hay muchas oportunidades para ti .

Pero si quieres conseguir trabajo como desarrollador web, necesitarás un buen sitio web como portafolio para poder mostrar tus habilidades y experiencia.

En este tutorial, discutiré algunas de las razones por los que debes construir tu propio portafolio web. Luego, te guiaré en el proceso de construcción de tu portafolio web responsivo con HTML, CSS y JavaScript.

Tabla de contenidos

¿Qué es un portafolio web de desarrollador?

Un  portafolio web de un desarrollador provee de información relevante sobre tus habilidades, experiencia y proyectos en los que hayas trabajado para empleadores potenciales.

Puedes considerar a tu  portafolio web como tu currículum en línea.

¿Porqué deberías tener un Portafolio web de Desarrollador?

1. Un Portafolio web incrementa tu presencia en línea

Como desarrollador, necesitas tener presencia en línea. Puedes hacer crecer tu presencia en línea utilizando plataformas de redes sociales tales como Twitter, Facebook, e Instagram. Pero esas plataformas no son completamente tuyas, ya que los moderadores de esas plataformas tienen casi control total sobre tu cuenta.

En cambio, tu portafolio web, está montado en tu propio dominio en línea.  Y la gente puede fácilmente encontrarte cuando hace una búsqueda de tu nombre en algún buscador como Google,  siempre que pongas las cosas correctas y en su lugar haciendo uso  de SEO (Search Engine Evaluation).

2. Un portafolio web es tu currículum en línea

Tu portafolio web es como tu currículum en línea. Clientes potenciales y Reclutadores de Recursos Humanos pueden encontrarte fácilmente en línea y revisar tus proyectos pasados y tus habilidades.

Esto también significa que cuando alguien te quiera dar una oportunidad para trabajar para ellos, y te pregunten por tus proyectos pasados, solamente les das el link a tu sitio web (tu portafolio). Que no solamente tiene tus proyectos, si no también tu conjunto de habilidades e información sobre tu experiencia pasada.

3. Un portafolio es evidencia de tu experiencia en tu área

Tener (y mucho menos construir tu propio) portafolio web como envía un claro mensaje como desarrollador de que estás poniendo tus habilidades en práctica y que realmente sabes lo que estás haciendo.

Un portafolio puede también ayudarte a construir confianza con clientes porque tienen evidencia de la calidad de tu trabajo.

Proyecto portafolio - Como construir tu propio portafolio en línea de desarrollador

Puedes crear tu propio  portafolio web con HTML, CSS y JavaScript, Y eso es lo que haremos aquí.

Ya hice esto hace algunos meses y lo puse a disposición de todos como un producto gratuito en Gumroad, así que decidí crear un tutorial sobre cómo lo hice.

Esta es la demostración de lo que construiremos.

Para seguir el proceso conmigo, puedes obtener los archivos de inicio de Github.

La estructura de carpetas del proyecto

Para evitar confusión, ordenaré el HTML, CSS, JavaScript, iconos e imágenes del proyecto en sus respectivas carpetas.

El archivo de HTML va en la carpeta root, y los archivos de imagen, icono, CSS, y JavaScript  estarán separados en sus respectivas subcarpetas  en una carpeta de assets. Esta es una práctica común.

ss1

También hay un archivo readme que contiene todas las herramientas que utilicé en el proyecto con sus respectivos enlaces. También está disponible en los archivos de inicio.

El código básico de HTML

Todos tienen sus preferencias al escribir código de un proyecto completo con HTML, CSS y JavaScript. A algunos les gusta definir todo el código HTML repetitivo primero y luego el CSS, pero a mí me gusta hacerlo todo sección por sección.

Entonces empezaré con la sección de la barra de navegación. Pero es bueno mostrar primero cómo se ve el código HTML básico:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />

    <!--Estilos CSS -->
    <link rel="stylesheet" href="assets/css/styles.css" />

    <!-- Favicons -->
    <link
      rel="apple-touch-icon"
      sizes="180x180"
      href="assets/icons/apple-touch-icon.png"
    />
    <link
      rel="icon"
      type="image/png"
      sizes="32x32"
      href="assets/icons/favicon-32x32.png"
    />

    <!-- Animaciones CSS CDN -->
    <link
      rel="stylesheet"
      href="https://cdnjs.cloudflare.com/ajax/libs/animate.css/4.1.1/animate.min.css"
    />
    <title>Jane Doe | Desarrolladora Web</title>
  </head>

  <body>
    <!-- Barra de Navegación -->

    <!-- Sección Hero  -->

    <!-- Sobre Mí -->

    <!-- Sección Habilidades -->

    <!-- Sección Proyectos -->

    <!-- Sección Contacto-->

    <!-- Sección de redes sociales - Fijado a la derecha -->

    <!-- Vuelve al comienzo  -->

    <!-- Sección Footer  -->

    <!-- Website scripts -->
    <script src="assets/js/app.js"></script>

    <!-- Ion icons scripts -->
    <script
      type="module"
      src="https://unpkg.com/ionicons@5.5.2/dist/ionicons/ionicons.esm.js"
    ></script>
    <script
      nomodule
      src="https://unpkg.com/ionicons@5.5.2/dist/ionicons/ionicons.js"
    ></script>
  </body>
</html>

Tengo todas las secciones comentadas en el HTML para que puedas seguirlas mejor. En la plantilla también hay Content Delivery Network (Red de Distribución de Contenido), también hay CDN para animaciones de CSS (Una Biblioteca de animación CSS), iconos de Ionic,  la librería de iconos que elegí para este proyecto.

Tengo un favicon hecho a través de Favicon IO  y lo vinculé en la sección head. Favicon es la pequeña imagen que se muestra en una pestaña del navegador.

La Sección de la barra de navegación

La barra de navegación contiene el logotipo simple del texto h1 y el menú de navegación:

 <nav>
      <h1>JANE DOE</h1>
      <ul class="navegacion">
        <li><a href="#sobremi" class="nav-link">Acerca de Mí</a></li>
        <li><a href="#habilidaes" class="nav-link">Habilidades</a></li>
        <li><a href="#proyectos" class="nav-link">Proyectos</a></li>
        <li><a href="#contacto" class="nav-link">Contacto</a></li>
      </ul>
      <button class="menu-hamburguesa" id="menu-hamburguesa">
        <ion-icon class="barras" name="menu-outline"></ion-icon>
      </button>
</nav>

Si te estás preguntando que representa el elemento botón,  son las barras para alternar el menú  de navegación en dispositivo móvil (menu de hamburguesa). Este estará escondido en nuestra versión de escritorio pero se mostrará en dispositivo móvil.

También vincularé las secciones individuales del sitio web a estos elementos de navegación, por lo tanto, cuando el usuario hace click en cualquiera de los elementos de navegación, se le lleva a la sección que corresponde al elemento de navegación en el que hace click.

Es por eso que tengo los atributos de referencia  (href) establecidos en #sobremi, #habilidades, #proyectos, and #contacto, respectivamente. La sección individual del sitio web tendrá estos atributos como ids.

La barra de navegación ahora luce así:

ss2

Como dar estilos a la barra de navegación

La barra de navegación necesita  definitivamente  algo de estilo para que se vea un poco mejor.

Antes de darle estilos a la barra de navegación, declararé algunas variables de CSS para facilitar las cosas más adelante.  Esto se debe a que, con las variables CSS, es más fácil evitar la redundancia y la repetición en tu archivo de CSS.

La sintaxis para declarar variables de CSS luce así:

:root {
  --variable-name: value;
}

Para usar la variable, debes hacer esto:

selector {
  propiedad: var(--nombre-variable);
}

También importaré la fuente Roboto de Google, y declararé algunos resets de CSS para remover algunas funciones predeterminadas, como el margin y padding para elementos, text-decoration para etiquetas anchor y list-style-type para listas.

@import url("https://fonts.googleapis.com/css2?family=Roboto:ital,wght@0,400;0,900;1,700&display=swap");

/* Variables */
:root {
  --font-family: "Roboto", sans-serf;
  --normal-font: 400;
  --bold-font: 700;
  --bolder-font: 900;
  --bg-color: #fcfcfc;
  --primary-color: #4756df;
  --secondary-color: #ff7235;
  --primary-shadow: #8b8eaf;
  --secondary-shadow: #a17a69;
  --bottom-margin: 0.5rem;
  --bottom-margin-2: 1rem;
  --line-height: 1.7rem;
  --transition: 0.3s;
}
/* Variables fin */

html {
  scroll-behavior: smooth;
}

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

ul {
  list-style-type: none;
}

a {
  text-decoration: none;
  color: var(--primary-color);
}

a:hover {
  color: var(--secondary-color);
}

body {
  font-family: var(--font-family);
}

Si lo notas, configuré un hover state para todos los enlaces del sitio web desde la línea 39 a la 41. Cuando el usuario se desplaza sobre cualquier enlace, cambia al color secundario que establecí en las variables de CSS.

Aquí hay una buena regla general para declarar variables CSS: si te encuentras usando la misma propiedad y el mismo valor a menudo en el mismo archivo CSS, puedes declarar una variable de css para evitar repetición.

También debes hacer que los nombres de tus variables sean lo más descriptivos posible, como hice yo, para ayudar a otros que podrían trabajar con tu código.

Con los resets, hay algunos cambios en la barra de navegación del navegador:

ss3

Para dar estilos a la barra de navegación y alinear su contenido, usaremos CSS Flexbox:

nav {
  position: sticky;
  top: 0;
  left: 0;
  z-index: 1;
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 1.5rem 3.5rem;
  background-color: var(--bg-color);
  box-shadow: 0 3px 5px rgba(0, 0, 0, 0.1);
}

¿Qué está haciendo el Código de CSS?

Le di a la barra de navegación el valor de sticky en la propiedad de position para que permanezca en la parte superior sin importar qué.

La propiedad de  z-index con el valor de 1  se asegura de que la barra de navegación se muestre sobre cualquier otro elemento de la página web. Así es como se hace sticky una barra de navegación.

Además, también apliqué una sombra en la parte inferior de la barra de navegación con la propiedad   box-shadow .

La barra de navegación tiene un nuevo aspecto:

ss4

Pero aún no hemos terminado. Los elementos del menú de navegación debe estar uno al lado del otro, no uno encima del otro. También lo haremos con Flexbox.

También terminaré el resto del estilo de  la barra de navegación haciendo que h1, los elementos de navegación y el botón de menú de hamburguesas se vean mejor. Haremos esto con algunas variables CSS declaradas inicialmente.

nav h1 {
  color: var(--color-primario);
}

nav a {
  color: var(--color-primario);
  transition: var(--transicion);
}
nav a:hover {
  color: var(--valor-secundario);
  border-bottom: 2px solid var(--valor-secundario);
}

nav ul {
  display: flex;
  gap: 1.9rem;
}

nav ul li {
  font-weight: var(--negrita);
}

El menú hamburguesa también necesita estar escondido. Tiene una clase de  .menu-hamburguesa, podemos aplicarle un atributo de display con valor de none y así haremos que el botón luzca mejor.

.menu-hamburguesa {
  color: var(--primary-color);
  font-size: 2rem;
  border: 0;
  background-color: transparent;
  cursor: pointer;
  display: none;
}

Nuestra barra de navegación luce más se ve mucho mejor ahora:

ss5

Como construir la sección Hero

La siguiente sección en la que trabajaremos. Esto no requerirá tanto trabajo como la barra de navegación.

La plantilla de HTML para la sección principal se encuentra en el fragmento de código a continuación:

<section class="hero" id="about">
      <img
        src="assets/images/wfh_1.svg"
        alt="jane-doe"
        loading="lazy"
        class="hero-img"
      />
      <div class="bio animate__animated animate__shakeX">
        <h2 class="bio-titulo">Sobre Mí</h2>
        <p class="bio-texto">
          Lorem ipsum dolor sit amet, consectetur adipisicing elit. Mollitia sed
          dolorem fugit sapiente porro veniam pariatur dolore nostrum delectus
          inventore tempore minus nemo, iste ullam illo laboriosam maiores
          repudiandae quos!
        </p>
      </div>
</section>

La única cosa que es un poco extraña son las clases de  animate__animated animate__shakeX aplicadas al div que contiene el texto de Sobre Mí .  Los nombres de clase son de CSS animado y son útiles para dar animación al container de texto Sobre Mí.

Con esto, el sitio web tiene un nuevo aspecto:

ss6

Como dar Estilo a la Sección Hero

Flexbox vendrá al rescate una vez más! Esta sección tiene dos conjuntos principales de contenido – una imagen y un texto en un div.  Podemos usar flexbox para mostrarlos uno al lado del otro. A continuación puedes ver como funciona en el fragmento de código de CSS :

.hero {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 2.5rem;
  max-width: 68.75rem;
  margin: auto;
}
ss7

Nuestra imagen de Jane Doe es muy grande, así que necesitamos reducir su anchura y altura. También necesitamos darle estilo al texto de bio (Sobre Mí texto) para legibilidad. Las variables de CSS que declaramos inicialmente serán muy útiles aquí.

.hero img {
  height: 37.5rem;
  width: 37.5rem;
}

.bio {
  width: 25rem;
  padding: 0.625rem;
  border-radius: 6px;
  box-shadow: 0px 2px 15px 2px var(--primary-shadow);
}

.bio h1 {
  margin-bottom: var(--bottom-margin);
}

.bio p {
  line-height: var(--line-height);
  padding: 0.3rem 0;
}

La sección hero ahora luce genial:

ss8

Como construir la sección Más Sobre Mí

Incluí esta sección para incluir más información sobre Jane Doe con un texto placeholder.

Puedes aprovechar esto para incluir información que no tuviste posibilidad de incluir en la sección Sobre Mí.

La Plantilla HTML para esta sección es sencilla y simple:

    <section class="mas-sobre">
      <h2>Más sobre mí</h2>
      <p>
        Lorem ipsum dolor sit amet consectetur adipisicing elit. Reiciendis
        nesciunt excepturi quos obcaecati incidunt voluptatem ipsam sunt ipsum,
        autem deleniti cupiditate molestias quis unde quae totam porro dicta
        iure animi inventore, veniam hic! Omnis nulla, delectus a voluptatibus
      </p>
      <p>
        Lorem ipsum dolor sit amet consectetur, adipisicing elit. Consequuntur
        nostrum dolor minus, libero delectus praesentium perferendis
      </p>
      <p>
        Lorem ipsum dolor sit amet consectetur adipisicing elit. Vero,
        consequuntur labore? Ea totam voluptas amet!
      </p>
    </section>

El CSS también es sencillo. Todo lo que haremos es configurar un  background-color con --bg-color  como variable de CSS, hacer que la sección sea legible configurando el padding, el margin y la line-height, y alinear el texto h2 al centro:

.mas-sobre {
  background-color: var(--bg-color);
  padding: 1rem 6rem;
}

.mas-sobre h2 {
  margin-bottom: var(--bottom-margin);
  text-align: center;
}

.mas-sobre p {
  line-height: var(--line-height);
  padding: 0.4rem;
}

En el navegador, la sección Más Sobre More luce así:

ss9

Como construir la sección de Habilidades

Desde la demostración en vivo,  verás que la sección de habilidades contiene habilidades relevantes como  HTML, CSS, JavaScript, etc. Pude conseguir los iconos de esos lenguajes en formato SVG en la página de Icons8 I.

La Plantilla de HTML para esta sección se encuentra en el fragmento de código a continuación:

 <section class="habilidades" id="habilidades">
      <h2 class="header-habilidadr">Mis mejores habilidades</h2>

      <div class="contenedor-habilidades">
        <div class="first-set animate__animated animate__pulse">
          <img
            src="assets/icons/icons8-html-5.svg"
            alt=""
            loading="lazy"
            class="icon icon-card"
          />
          <img
            src="assets/icons/icons8-css3.svg"
            alt=""
            loading="lazy"
            class="icon icon-card"
          />
          <img
            src="assets/icons/icons8-javascript.svg"
            alt=""
            loading="lazy"
            class="icon icon-card"
          />
        </div>

        <div class="second-set animate__animated animate__pulse">
          <img
            src="assets/icons/icons8-bootstrap.svg"
            alt=""
            loading="lazy"
            class="icon icon-card"
          />
          <img
            src="assets/icons/icons8-react-native.svg"
            alt=""
            loading="lazy"
            class="icon icon-card"
          />
          <img
            src="assets/icons/icons8-git.svg"
            alt=""
            loading="lazy"
            class="icon icon-card"
          />
        </div>
      </div>
    </section>

Hay seis iconos en total. Y en lugar de tener que alinearlos con Flexbox, los agruparemos en dos lugares (3 cada uno),  con las clases de primer y segundo conjunto, para que se mantengan uno encima del otro. Esto significa que los estilos que aplicaremos serán más legibles. ¡Fácil!

Tengamos en cuenta que hemos adjuntado el atributo de carga a los íconos e imágenes individuales y configurándolo en lazy. Esto asegurará que las imágenes se carguen solo cuando el usuario se desplace a las secciones que las contienen.

Como aplicar estilos a la sección de Habilidades

Sin aplicar estilos, la sección de estilos luce así:

ss10edited

Debemos dar un poco de estilos a la sección por que aun no se ve lo suficientemente bien::

.habilidades {
  max-width: 68.75rem;
  margin: auto;
  text-align: center;
  margin-top: 2.5rem;
}

.encabezado-habilidad {
  margin-bottom: 1rem;
}

.contenedor-habilidad img {
  padding: 1.25rem;
}

.icono {
  width: 11.875rem;
  height: 11.25rem;
}

En el CSS de arriba, establecimos un ancho máximo para toda la sección para posicionar los elementos al centro del navegador para una mejor experiencia de usuario.

Otros estilos que aplicamos están relacionados a claridad y la legibilidad. Por ejemplo, Incrementamos el tamaño de los iconos para hacerlos más visibles con sus propiedades de alto y ancho. También aplicamos un padding de 1rem (16pixeles) a todos los iconos para dar un poco de espacio entre ellos .

La sección de habilidades ahora luce mejor:

ss11

Y aún así, creo que la sección puede lucir mejor, así que he decidido hacer algunos ajustes más con la propiedad box-shadow:

Recordemos que en el HTML hay un atributo de clase llamado  .tarjeta-icono adjunto a todos los iconos. I will be using the class name to put all the icons in a card:

.tarjeta-icono {
  background-color: #fff;
  border-radius: 11px;
  box-shadow: 0 3px 10px var(--secondary-shadow);
  padding: 20px;
  margin: 10px;
}

La sección de habilidades ahora debe lucir mejor:

ss12

¡Mira eso!

Como construir la sección de Proyectos

Uno de los propósitos principales de un sitio web portafolio es mostrar tus proyectos. Por lo tanto, tendremos que crear una sección para mostrar los proyectos en los que has trabajado en el pasado.

Esta sección es probablemente la más tediosa en aplicar estilos, pero Flexbox (Modelo de Caja) no dejará de ser nuestro amigo.

La estructura de HTML para esta sección se encuentra en el fragmento de código más abajo:

<section class="proyectos" id="proyectos">
      <h2 class="titulo-de-proyectos">Algunos de mis proyectos recientes</h2>
      <div class="contenedor-de-proyectos">
        <div class="contenedor-de-proyectos tarjeta-de-proyectos">
          <img
            src="assets/images/expenseTracker.png"
            alt="rastreador-de-gastos"
            loading="lazy"
            class="project-pic"
          />
          <h3 class="titulo-de-proyectos">Rastreador de Gastos</h3>
          <p class="detalle-de-proyectos">
            Lorem, ipsum dolor sit amet consectetur adipisicing elit. Quas
            ratione vel inventore labore commodi modi quos culpa aut saepe!
            Alias!
          </p>
          <a href="#" target="_blank" class="enlace-de-proyecto">Check it Out</a>
        </div>
        <div class="contenedor-de-proyectos tarjeta-de-proyectos ">
          <img
            src="assets/images/netflixClone.png"
            alt="netflic-clone"
            loading="lazy"
            class="project-pic"
          />
          <h3 class="titulo-proyecto">Netflix Clone</h3>
          <p class="detalles-proyecto">
            Lorem, ipsum dolor sit amet consectetur adipisicing elit. Quas
            ratione vel inventore labore commodi modi quos culpa aut saepe!
            Alias!
          </p>
          <a href="#" target="_blank" class="project-link">Check it Out</a>
        </div>
        <div class="contenedor-de-proyecto tarjeta-de-proyecto">
          <img
            src="assets/images/greenyEarth.png"
            alt="greeny-earth"
            loading="lazy"
            class="project-pic"
          />
          <h3 class="titulo-de-proyecto">Greeny Earth</h3>
          <p class="detalles-de-proyecto">
            Lorem, ipsum dolor sit amet consectetur adipisicing elit. Quas
            ratione vel inventore labore commodi modi quos culpa aut saepe!
            Alias!
          </p>
          <a href="#" target="_blank" class="enlace-de-proyecto">Echale un vistazo!</a>
        </div>
      </div>
    </section>

Revisando el HTML, hay tres proyectos en total, en sus elementos divs individuales con el nombre de clase contenedor-de-proyecto y tarjeta-de-proyecto. Estas clases serán muy relevantes en aplicar estilos consistentemente al proyecto.

El elemento de sección contenedor en sí mismo tiene una clse de proyectos y un atributo de identificación de proyectos también. El nombre de la clase es para diseñar los estilos y la identificación es para vincularla al enlace Proyectos en la barra de navegación.

Los proyectos tienen sus imágenes individuales con el nombre de clase  of foto-proyecto,  sus títulos con una clase  titulo-de-proyecto, detalles con el nombre de clase detalles-de-proyecto, y en laces con la clase de  enlaces-de-proyecto.

El único propósito de darle a todos los elementos clases únicas es para aplicarles estilos.

Estos son algunos de los proyectos en los que trabajé cuando empecé como desarrollador.

La sección de proyectos luce así en el navegador:

projects-unstyled

Sin embargo, la sección no se ve tan bien, incluso hay una molesta barra de desplazamiento horizontal causada por las imágenes. Así que tenemos mucho trabajo por hacer en CSS.

Como dar estilos a la sección de Proyectos

En primer lugar, daré a toda la sección un color de fondo configurando el color grisáceo (--bg-color) que declaramos en las variables CSS como valor.

También reduciré el ancho y el alto de las imágenes del proyecto usando la clase  foto-de-proyecto .  Luego usaré Flexbox para poner los proyectos uno al lado del otro.

.proyectos {
  background-color: var(--bg-color);
  padding: 32px 0;
  margin-top: 2rem;
}

.foto-de-proyecto {
  width: 65%;
  height: 60%;
}

.contenedor-de-proyectos {
  display: flex;
  align-items: center;
  justify-content: center;
}

La sección ahora luce mejor:

ss13Edited

Las imágenes ahora lucen mejor, pero el título del proyecto, detalles de proyecto, y enlaces de proyectos necesitan alinearse muy bien dentro de sus contenedores individuales.  

Toda la sección del proyecto también debe ser empujada hacia el centro. Sin embargo, no necesita Flexbox para hacer esto  se puede hacer configurando la propiedad de text-align con el valor de center:

.titulo-de-proyectos {
  text-align: center;
  margin-bottom: 1rem;
}

.contenedor-de-proyectos {
  text-align: center;
  width: 21.875rem;
  padding: 1rem;
}

Debemos tener en cuenta que también estable un ancho de 21.875rem (350 pixeles)  para los contenedores de proyectos individuales. Esto los separará de los lados para una mejor experiencia de usuario. En este caso, el usuario no necesitaría mirar completamente para ver todo.

La sección ahora luce mejor:

ss14

Aún podemos hacer que esta sección se vea mejor. Los títulos de proyectos, detalles de proyectos y los enlaces de proyectos  se ven agrupados, por lo que debemos agregar algo de padding y margin.

Los contenedores de proyectos individuales también deben verse más distintos. La propiedad  box-shadow va ser fundamental aquí, así que las pondremos en sus tarjetas individuales.

.contenedor-de-proyecto p {
  padding: 0.4rem;
}

.titulo-de-proyecto {
  margin-bottom: var(--bottom-margin);
}

.detalles-de-proyecto {
  margin-bottom: var(--bottom-margin);
}

.tarjeta-de-proyecto {
  background-color: #fff;
  border-radius: 11px;
  box-shadow: 0 3px 10px var(--primary-shadow);
  padding: 20px;
  margin: 10px;
}

La sección de proyectos ahora luce mejor:

ss15

Como construir la sección Contacto

Si un potencial empleador o cliente encuentra tu portafolio website atractivo, podrían querer contactarte. Así que te recomendamos tener un formulario de contacto en esta sección, junto con enlaces para tus cuentas de redes sociales.

El HTML para esta sección se vería así:

<section class="contacto" id="contacto">
      <h2>Contactame</h2>
      <div class="formulario-contacto-contenedor">
        <div class="formulario-contacto">
          <form action="https://formspree.io/f/xyylngw" method="POST">
            <div class="control-formulario">
              <label for="name">Nombre</label>
              <input
                type="text"
                id="name"
                name="sender-name"
                placeholder="Escribe tu nombre"
                class="input-field"
                required
              />
            </div>
            <div class="control-formulario">
              <label for="email">Correo Electrónico</label>
              <input
                type="email"
                id="email"
                name="sender-email"
                placeholder="Ingreso tu correo electrónico"
                class="input-field"
                required
              />
            </div>
            <div class="control-formulario">
              <label for="mensaje">Mensaje</label>
              <textarea
                id="mensaje"
                cols="60"
                rows="10"
                placeholder="Escribe tu mensaje"
                name="mensaje"
                class="input-field"
                required
              ></textarea>
            </div>
            <input
              type="submit"
              value="Enviar"
              id="submit-btn"
              class="submit-btn"
            />
          </form>
        </div>
      </div>
    </section>

Aquí construimos el formulario de contacto con campos de entrada para nombre y correo electrónico, una etiqueta textarea para que la gente escriba el mensaje que quieran enviar, y el botón enviar para enviar el mensaje para que puedas verlo.

Si echas un vistazo al elemento form, verás que tenemos un atributo de acción establecido en una URL de  Formspree. Este es el que hemos elegido para el envío de formulario. Con Formspree, puedes recibir el mensaje directamente a la bandeja de entrada de tu correo electrónico sin necesidad de configurar un servidor con PHP o JavaScript complejos.

Ten en cuenta que no podrás usar mi URL -no funcionará para ti. Puedes fácilmente configurar el tuyo en el sitio web de Formspreee de forma gratuita.  También adjunté un recurso sobre cómo configurar Formspree en el archvio de readme del proyecto.

Establecí algunos atributos  id y class  para los inputs individuales para darle estilos. También hay un atributo  name para todos los campos de input. Esto es requerido por el servicio de envió de formularios de Formspree.

Para obtener una validación básica, adjunté un atributo  required , de esa forma,  el formulario se niega a enviar la información si el usuario deja algún campo vacío.

Como dar estilo a la sección Contacto

Sin estilo, la sección de contacto no se ve nada bien:

ss16Edited

Todo lo que haremos en CSS  es alinear todo el contenido al centro y hacer que los campos de input se vean mejor.

Con las propiedades de text align y margin, puedes alinear la etiqueta h2 y el contenedor para el formulario del contacto al centro .

También pondremos todo el formulario en una tarjeta con la propiedad de box-shadow .

.contacto {
  margin-top: 2rem;
}

.contacto h2 {
  text-align: center;
  margin-bottom: var(--bottom-margin-2);
}

.contenedor-formulario-contacto {
  max-width: 40.75rem;
  margin: 0 auto;
  padding: 0.938rem;
  border-radius: 5px;
  box-shadow: 0 3px 10px var(--secondary-shadow);
}
ss17

Los inputs, textarea, labels y los placeholders necesitan definitivamente también algo de estilo para ayudar con la alineación y la claridad:

.contenedor-formulario-contacto label {
  line-height: 2.7em;
  font-weight: var(--bold-font);
  color: var(--primary-color);
}

.contenedor-formulario-contacto textarea {
  min-height: 6.25rem;
  font-size: 14px;
}

.contenedor-formulario-contacto .input-field {
  width: 100%;
  padding-top: 10px;
  padding-bottom: 10px;
  border-radius: 5px;
  border: none;
  border: 2px outset var(--primary-color);
  font-size: 0.875rem;
  outline: none;
}
ss18
El formulario luce mejor

Pero los placeholders no son consistentes con las etiquetas. Así que necesitamos darle algo de color y padding. Le daremos el conjunto de color primario que asignamos en la lista de Variables de CSS.

Para seleccionar los placeholders y darle estilos, podemos usar la pseudo-class placeholder :

.input-field::placeholder {
  padding: 0.5rem;
  color: var(--primary-color);
}
ss19

En el formulario de contacto, lo único que falta es dar estilo al elemento button. Los botones son bastante fáciles de estilizar:

.submit-btn {
  width: 100%;
  padding: 10px;
  margin: 10px 0;
  background-color: #fff;
  border: 2px solid var(--primary-color);
  border-radius: 5px;
  font-size: 1rem;
  font-weight: var(--bold-font);
  transition: var(--transition);
}

En el fragmento de código de CSS anterior, hice que el botón pasara por todo el contenedor del formulario dándole un ancho del 100%. También lo hice más visible dando padding, margin, un borde  y más  font-weight.

La propiedad de border-radius con un valor de 5px  remueve las bordes afilados y la transición sirven para  ralentizar un poco las cosas cuando el botón está en estado de desplazamiento.

El estado de hover  se define en el fragmento de código CSS a continuación:

.submit-btn:hover {
  background-color: var(--primary-color);
  border: 2px solid var(--primary-color);
  cursor: pointer;
}

El formulario luce mucho mejor ahora:

contact-form-hover-effect

Recuerda  que tener tus enlaces de redes sociales en tu sitio web portafolio es de gran ventaja para que cualquier persona interesada en contactarte lo haga.  Este es el siguiente paso que realizaremos, y lo haremos de una forma única.

El  código de HTML para los botones de redes sociales está en el fragmento  abajo:

    <div class="sociales">
      <a href="#" target="_blank"
        ><img
          src="assets/icons/icons8-twitter-circled.gif"
          alt="Twitter"
          loading="lazy"
          class="socicon"
      /></a>
      <a href="#" target="_blank"
        ><img
          src="assets/icons/icons8-instagram.gif"
          alt="Instagram"
          loading="lazy"
          class="socicon"
      /></a>
      <a href="#" target="_blank"
        ><img
          src="assets/icons/icons8-linkedin-circled.gif"
          alt="Linkedin"
          loading="lazy"
          class="socicon"
      /></a>
      <a href="#" target="_blank"
        ><img src="assets/icons/icons8-github.gif" alt="Github" class="socicon"
      /></a>

Los iconos de redes sociales que elegiremos son gifs animados de la plataforma icons8. Colocaremos a todos en el mismo contenedor con la clase de sociales, y les daremos una clase individual de socicon para dar estilos más fácilmente.

Debajo puedes ver unos iconos  de redes sociales animados que parpadearan en nuestro sitio web:

animated-social-icons

Como dar estilos a los iconos de redes sociales

.sociales {
  display: flex;
  flex-direction: column;
  position: fixed;
  right: 1%;
  bottom: 50%;
}

.socicon {
  width: 2rem;
  height: 2rem;
}

Con el CSS de arriba, los iconos de redes sociales estarán fijos al lado derecho del sitio web, así que todos los que visiten el sitio web podrán visualizar siempre los iconos aún cuando el usuario se desplace hacia abajo por la página.

También reduciremos el tamaño de los iconos asignándoles a todos sus valores de  propiedad de  width y height .

good-icons

Mira el resultado!

Lo único que nos falta es el footer.  No hay nada complejo en el HTML y CSS de footer, aparte de la entidad de caracteres reservados para el símbolo de derechos de autor y el corazón:

<footer>
      <p class="copy">&copy; Copyright 2021</p>
      <p class="copy">
        Built with &#x2661; by
        <a href="https://twitter.com/koladechris" target="_blank"
          >Kolade Chris (Ksound)</a
        >
      </p>
</footer>
footer {
  background-color: var(--bg-color);
  padding: 1.25rem;
  text-align: center;
  margin: 2rem 0 0;
}

Ahora tenemos un sitio web portafolio completo!

full-fledged-portfolio

Pero necesitamos hacerlo responsivo, porque en su estado actual no se vería bien en dispositivo más chicos:

unresponsive-portfolio

Necesitamos hacer que todo el contenido de las secciones individuales se muestre en una sección encima de la otra ( en un diseño de columna) . Podemos hacer esto muy fácilmente con media queries y Flexbox.

Antes de agregar las media queries para la responsividad de nuestra página, vamos a implementar un botón de desplazarse-hacia-arriba con HTML, CSS, y JavaScript.

Como Agregar un Botón de Desplazarse hacia Arriba

El HTML para el botón Desplazarse hacia Arriba

Para el HTML, tenemos un icono animado de Icons8 y al que asignaremos en una etiqueta de i.

La etiqueta de i tiene una clase de desplazarse-hacia-arriba  para dar estilos y un id de desplazarse-hacia-arriba   para seleccionarlo con  JavaScript. Esto se debe a que para nuestros proyectos, recomiendo usar clases  para dar estilos y ids para las funcionalidades que agregaremos con JavaScript.

  <i class="desplazarse-hacia-arriba" id="desplazarse-hacia-arriba"
      ><img
        src="assets/icons/icons8-upward-arrow.gif"
        class="socicon up-arrow"
        alt="desplazarse-hacia-arriba"
    /></i>

Como dar estilos al icono de Desplazarse-hacia-Arriba

Haremos que el icono de desplazarse-hacia-arriba tenga una propiedad de fixed para que se quedé estático como los iconos de redes sociales. También le daremos una propiedad de pointer al cursor, para que este cambie cuando posicionamos el cursor encima del icono.

Con la clase de flecha-arriba al icono de desplazarse-hacia-arriba, incrementaremos el tamaño del icono para visibilidad:

.desplazarse-hacia-arriba {
  position: fixed;
  right: 0.5%;
  bottom: 3%;
  cursor: pointer;
}

.flecha-arriba {
  width: 3rem;
  height: 3rem;
}

El icono se ve muy bien:

scroll-up-first

Pero aún no hace nada. Así que necesitamos hacerlo funcional con algunas lineas de JavaScript:

// funcionalidad de desplazar hacia arriba
const desplazarArriba = document.querySelector("#desplazarse-hacia-arriba");

desplazarArriba.addEventListener("click", () => {
  window.scrollTo({
    top: 0,
    left: 0,
    behavior: "smooth",
  });
});

¿Qué está haciendo el código de arriba?

La primera línea selecciona el botón de desplazar-hacia-arriba con el atributo id adjunto a el en el HTML. Usamos el método querySelector() aquí. También podríamos utilizar el método getElementById() .

En las líneas restantes, usamos el  eventListener del click para obtener la acción click del usuario  y hacer que reaccione la parte  de scrollTo del objeto de Windows para que el botón funcione.

Con esta funcionalidad, cuando el usuario hace click en el botón desplazar-hacia-arriba, la página se desplaza hacia arriba y al lado izquierdo del sitio web suavemente.  Hicimos esto configurando las propiedades top a 0, left a 0, y   behavior a smooth.

scroll-up

Puedes aprender más sobre el objeto windows abriendo la consola de herramientas de desarrollo del navegador. Escribe en la ventana y da enter, luego verás todo lo disponible en el objeto de Windows, como lo hacemos a continuación:

window-object

Como hacer Responsivo tu Portafolio web

Para hacer responsivo tu sitio web, usaremos media queries de CSS y Flexbox.

Primero, necesitaremos hacer que las imágenes y el texto se vean más pequeños, y luego haremos que el contenido de cada sección se muestre en un diseño vertical configurando la propiedad flex-direction a column.

En la consulta de medios, estaremos usando 2 breakpoints  – 720px y 420px.

El breakpoint de 720px  es para tabletas y teléfonos móviles, y el de 420px es para teléfonos pequeños como un  iPhone 6,  y teléfonos Android pequeños.

Los breakpoints de la consulta de medios son los puntos en el que queremos que el contenido del sitio web responda de acuerdo al ancho del dispositivo. Así que, cualquier código que pongamos debajo del breakpoint de 720px se refleje en dispositivos con una pantalla menor o mayor de 720px, dependiendo de como especifiques el ancho máximo o ancho mínimo.

En el caso de  utilizar un max-width of 720px,  la sintaxis de la consulta de medios luce así:

@media screen and (max-width: 720px) {
  /* los cambios se reflejan en una pantalla con un ancho de 720px ye inferior */
}

Como crear la Consulta de Medios para Tabletas y Teléfonos móviles (max-width 720px)

Empezaremos por hacer el sitio responsiv0  desde la barra de navegación, porque  comúnmente la barra de navegación no se ve bien en dispositivos más pequeños.

ss21

Primero, vamos a reducir el padding de la barra de navegación para que el logo de   h1 l y los elementos del menú de navegación encajen bien:

nav {
    padding: 1.5rem 1rem;
  }

Las cosas ahora se ven un poco mejor:

ss22

En dispositivos más pequeños, los elementos del menú de navegación deben estar uno encima del otro y deben estar ocultos. Entonces, es hora de actualizar el código para que el menú de hamburguesas esté inicialmente oculto.

Como construir el menú de hamburguesas

Para hacer el menú de hamburguesas, debemos sacar los elementos del menú de navegación del viewport.  Luego, debemos establecer una clase de presentacion  en los elementos de la lista de navegación que se alternarán con unas pocas líneas de JavaScrip (recordemos que los elementos de navegación están en una lista desordenada).

 nav ul {
    position: fixed;
    background-color: var(--bg-color);
    flex-direction: column;
    top: 86px;
    left: 10%;
    width: 80%;
    text-align: center;
    transform: translateX(120%);
    transition: transform 0.5s ease-in;
  }

   nav ul li {
    margin: 8px;
  }

En el fragmento  anterior de código CSS, establecimos una posición de fixed en la lista desordenada (ul) para que flote en la pantalla. También lo empuje 86px hacia abajo desde la parte superior con top: 86px y 10% a la izquierda.

Le dimos un ancho de 80% en relación a su elemento padre (el elemento de navegación del HTML), lo empujó hacia el centro context-align: center,  y finalmente lo oculto con la propiedad de transformación establecida en translateX(120%). Esto lo empujará hacia la derecha y lo sacará del viewport.

Y ahora, cuando el usuario de click para mostrar los elementos de la barra de navegación, todos se deslizan desde la derecha. Impresionante.

Si quieres que los elementos de la barra de navegación se deslicen desde la izquierda, cambia el valor de la propiedad  transform a transform: translateX(-120%) (esto es el opuesto directo de transform: translateX(120%)). Es tan fácil como eso, dependiendo de tu preferencia.

También asigné un margen de 8px a los elementos de navegación para darles más espacio.

La barra de navegación ahora luce así:

ss22-1

El menú de hamburguesas permanece oculto.  Por lo tanto, necesitamos mostrarlo dandole un display: block, asignándole una clase de show para en la propiedad transform dar el valor de 0 en el eje-X translateX(0) para mostrarlo, y después interactuar con el usando  JavaScript .

 .menu-hamburguesa {
    display: block;
  }

  nav ul.show {
    transform: translateX(0);
  }
ss24

Nuestro menú de hamburguesa puede mostrarse, pero los elementos de la barra de navegación están ocultos. Para mostrarlos, necesitamos activar y desactivar la clase show con JavaScript.

Escribiendo JavaScript para hacer el Menú de Hamburguesa

Para activar y desactivar con JavaScript los elementos del menú de la barra de navegación, necesitamos primero seleccionar todos los elementos relevantes de la barra de navegación y guardarlos en algunas variables:

// Selecciones para Barra de navegación hamburguesa

const burger = document.querySelector("#burger-menu");
const ul = document.querySelector("nav ul");
const nav = document.querySelector("nav");
  • La variable  burger seleccionan la barra de menú de hamburguesa.
  • La variable ul  selecciona los elementos de la lista (los enlaces de navegación en conjunto ).
  • La variable nav selecciona el propio contenedor (el elemento de navegación).

Lo siguiente que necesitamos hacer es activar la clase de  nav ul.show  cuando el  usuario hace click en el menú  de hamburguesa de la barra de navegación. Haremos esto agregando un  eventListener  click al menú de hamburguesa del barra de menú, y después usar el método para activar  to the hamburger menu bar, y luego usando el método de alternar para eliminar y agregar la clase de show. show.

Recordemos que lo seleccionamos y lo guardamos en una variable llamada  burger.

burger.addEventListener("click", () => {
  ul.classList.toggle("show");
});

Nuestros elementos de navegación ahora se pueden activar y desactivar:

nav-toggling-quirk

Pero hay un problema – la barra de navegación en móvil no se oculta cada vez que se hace click en cualquiera de los enlaces de los elementos de navegación. Por lo tanto, debemos eliminar la clase de nav ul.show cuando se hace click en cualquiera de los enlaces del elemento de navegación.

Podemos hacer esto con solo algunas líneas de JavaScript también:

// Cerrar el menú de hambuguesa cuando se hace click en un enlace  

// Seleccionar enlaces de navegación
const navLink = document.querySelectorAll(".nav-link");

navLink.forEach((link) =>
  link.addEventListener("click", () => {
    ul.classList.remove("show");
  })
);

Recuerda que los enlaces de navegación tienen una clase de enlace de navegación del HTML. Así que los seleccioné todos con esa clase y los puse en una variable llamada  nav-link.  Hicimos esto con el método  querySelectorAll() .

Luego recorrí todos los enlaces con el método forEach de arreglos y puse un event listener  de click en todos ellos. Después usé el método remove() proporcionado por el DOM para eliminar la clase de show cada vez que se hace click en cualquiera de los elementos del menú de navegación. Esto sacará  del viewport todos los elementos de la lista.

nav-toggling-quirk-fixed

Mira eso !

Esto es un gran avance. Con lo que hemos cubierto ya puedes hacer un menú de hamburguesa para cualquier sitio web.

Como hacer responsiva la sección Hero

La sección Hero no se ve muy bien actualmente:

ss25

Todo lo que tenemos que hacer es usar la propiedad flex-direction con un atributo de column en la consulta de medios, reducir el ancho y altura de la imagen de Jane Doe, y hacer que el texto de Sobre Mí (bio texto)  sea legible.

.hero {
    margin-top: -4rem;
    flex-direction: column;
    gap: 0;
  }

  .hero img {
        height: 37.5rem;
        width: 30rem;
    }

  .bio {
    margin-top: -7rem;
    width: 20.5rem;
  }

La sección hero luce mejor ahora :

ss26

Como hacer responsiva la sección de Más Sobre mí

La sección de Más sobre mí no se ve tan mal, pero claramente podemos hacer algo por mejorarla:

ss27

Tenemos el siguiente código de CSS para hacerlo más legible y presentable:

 .mas-sobre {
    margin-top: 2rem;
    padding: 1rem 3.5rem;
  }

  .mas-sobre h2 {
    text-align: center;
  }

  .mas-sobre p {
    text-align: justify;
  }

Movimos toda la sección un poco hacia abajo y le incrementamos el padding en todos sus lados, alineamos el  h2 al centro, y justificamos el texto.

ss28

Como hacer responsiva la sección de Habilidades

Los iconos de habilidades lucen muy grandes:

ss29

Todo lo que tenemos que hacer en la consulta de medios es reducir el tamaño de todos los iconos con las propiedades de width y height: :

.icono {
    width: 5.875rem;
    height: 5.25rem;
  }
ss30

Como hacer responsiva la sección de Proyectos

En esta sección de proyectos, necesitamos hacer que los tres proyectos se apilen uno encima del otro configurando la propiedad de flex-direction a column. También reduciremos un poco  el ancho de los contenedores individuales.

 .contenedor-proyectos {
    flex-direction: column;
  }

  .contenedor-proyecto {
    width: 20.875rem;
  }

Como hacer responsivo el formulario de Contacto

Necesitamos reducir el ancho del formulario de contacto para alejarlo de los lados y asegurarse de que los iconos fijos de las redes sociales no estén encima.

Todo lo que necesitamos es establecer un ancho máximo:

 .contenedor-formulario-de-contacto {
    max-width: 23.75rem;
  }

El formulario de contacto ahora se ve mejor:

ss32

Como hacer responsivo el sitio web para teléfonos pequeños

En teléfonos pequeños como el iPhone 6, 7, y 8 plus, los iconos de redes sociales y el icono de desplazamiento-hacia-arriba no se muestran. También hay una barra de desplazamiento horizontal.

smaller-phones-responive-quirks

Para corregir estas peculiaridades, agregaremos consulta de medios en un breakpoint de 420px:

@media screen and (max-width: 420px) {
  .hero img {
    height: 37.5rem;
    width: 23rem;
  }

  .bio {
    width: 18.3rem;
  }

  .contenedor-proyecto {
    width: 17.875rem;
  }

  .contenedor-formulario-de-contacto{
    max-width: 17.75rem;
  }
} 

Reduje el tamaño de nuestra imagen de Jane Doe y también reduje el ancho del texto de la biografía (Texto Acerca de Mí), el contenedor del proyecto, y el formulario de contacto.

Todos estos cambios harán que se muestren los iconos fijos en el lado derecho del sitio web: las redes sociales y los iconos de desplazamiento-hacia-arriba.

smaller-phones-responsiveness-quirk-fixed

Ahora todo se ve bien:

fully-responsive

Ese es el final de todo. Tenemos un portafolio de nuestro sitio web totalmente responsivo.

Puedes descargar la versión final en el archivo formato zip desde este repositorio de GitHub repo.

También puedes consultar la  live demo  del sitio web del portafolio. Tiene un archivo readme que contiene información sobre las herramientas que utilicé y como puedes personalizar el sitio web.

Conclusión

En este tutorial, aprendiste que es un portafolio de un desarrollador web y las razones por las que deberías tener uno.

También aprendiste como hacer un sitio web portafolio completamente responsivo usando HTML, CSS, y  JavaScript.

Las partes diferentes de este tutorial son cada uno de de los proyectos, que combinados, se convierten en un sitio web más grande. Por ejemplo, puedes hacer el diseño de una tarjeta, una barra de menú responsiva, un formulario de contacto funcional, y un botón de desplazamiento-hacia-arriba, ya que el tutorial los cubre todos.

Siéntete libre de personalizar el sitio web a tu gusto .

Si encuentras útil este tutorial, puedes compartirlo con tus amigos y familiares. Realmente lo apreciaría.