Advertisement
  1. Web Design
  2. UX/UI
  3. Forms

Cómo crear un formulario SVG responsivo hecho a mano

Scroll to top
Read Time: 9 min

() translation by (you can also view the original English article)

En tutoriales anteriores, te he enseñado cómo crear un formulario responsivo con flexbox además de cómo estilizar los elementos de un formulario. Hoy continuaremos el viaje por el mundo de los "formularios" y aprenderemos a crear un formulario SVG responsivo hecho a mano desde cero.

Este es el formulario que vamos a crear:

1. Comienza con el marcado de la página

Vamos a comenzar con un SVG y un elemento form:

1
<svg style="display:none;">...</svg>
2
<form class="handmade-form">...</form>

Sprites de SVG

Para nuestro formulario vamos a necesitar una serie de ilustraciones hechas a mano. Afortunadamente, Ian Yates, el editor de diseño web aquí en Tuts+, creó algunas bonitas ilustraciones para nosotros. Gracias, Ian.

De manera similar a como lo hicimos en un tutorial anterior, vamos a crear un sprite de SVG e incrustaremos todos los dibujos en su interior. Después, dentro del formulario, mostraremos el icono en cuestión cada vez que lo necesitemos llamando al elemento use.

Este es el marcado para el sprite de SVG:

1
<svg style="display:none;">
2
  <symbol id="input1" viewBox="0 0 347.11 49.7" preserveAspectRatio="none">...</symbol>
3
  <symbol id="input2" viewBox="0 0 345.27 56.51" preserveAspectRatio="none">...</symbol>
4
  <symbol id="input3" viewBox="0 0 344.17 48.76" preserveAspectRatio="none">...</symbol>
5
  <symbol id="input4" viewBox="0 0 347.13 54.94" preserveAspectRatio="none">...</symbol>
6
  <symbol id="textarea" viewBox="0 0 704.84 271.56" preserveAspectRatio="none">...</symbol>
7
  <symbol id="fieldset" viewBox="0 0 998.06 602.62" preserveAspectRatio="none">...</symbol>
8
  <symbol id="checkbox_empty" viewBox="0 0 33.18 33.34">...</symbol>
9
  <symbol id="checkmark" viewBox="0 0 37.92 33.3" preserveAspectRatio="none">...</symbol>
10
  <symbol id="button" viewBox="0 0 256.6 60.02" preserveAspectRatio="none">...</symbol>
11
</svg>

Toma en cuenta el atributo preserveAspectRatio="none" que agregamos a la mayoría de las ilustraciones. Hicimos esto porque, como veremos más adelante, la escala de nuestros iconos cambiará y estos perderán sus dimensiones iniciales.

Formulario

El formulario estará compuesto por un encabezado y una lista desordenada. Además, utilizaremos un .container para establecer un ancho máximo para el formulario y para centrar horizontalmente su contenido:

1
<form class="handmade-form">
2
  <div class="container">
3
    <h1>Contact us</h1>
4
    <ul>
5
      <li class="grid grid-2">...</li>    
6
      <li class="grid grid-2">...</li>    
7
      <li class="form-wrapper">...</li>    
8
      <li class="form-wrapper">...</li>    
9
      <li class="grid grid-3">...</li>
10
    </ul>
11
  </div>
12
</form>

Como puedes ver, cada uno de los elementos de la lista anterior contiene una o más clases. Alternativamente, por razones de legibilidad, pudimos haber creado un elemento hijo adicional para  enviarle esas clases, de esta manera:

1
<li>
2
  <div class="grid grid-2">...</div>
3
</li>

Vamos a colocar los SVGs y los elementos del formulario en el interior de la lista.

El primer elemento de la lista incluirá dos campos de entrada obligatorios junto con sus SVGs:

1
<div class="form-wrapper">
2
  <input type="text" placeholder="Name*" required> 
3
  <svg>
4
    <use xlink:href="#input1"></use>
5
  </svg>
6
</div>
7
<div class="form-wrapper">
8
  <input type="text" placeholder="Surname*" required>
9
  <svg>
10
    <use xlink:href="#input2"></use>
11
  </svg>
12
</div>

De la misma manera, el segundo elemento de la lista también tendrá dos campos de entrada junto con sus SVGs:

1
<div class="form-wrapper">
2
  <input type="email" placeholder="Email*" required> 
3
  <svg>
4
    <use xlink:href="#input3"></use>
5
  </svg>
6
</div>
7
<div class="form-wrapper">
8
  <input type="tel" placeholder="Phone">
9
  <svg>
10
    <use xlink:href="#input4"></use>
11
  </svg>
12
</div>

Dentro del tercer elemento de la lista, colocaremos un textarea y su ilustración asociada:

1
<textarea placeholder="Message"></textarea>       
2
<svg>
3
  <use xlink:href="#textarea"></use>
4
</svg>

El cuarto elemento de la lista incluirá un elemento fieldset. En su interior colocaremos un elemento legend, una lista con dos botones de radio junto con sus SVGs, y su SVG relacionado.

1
<fieldset>
2
  <legend>Select preferred method of contact</legend>
3
  <ul class="checkbox-list">
4
    <li>
5
      <input type="radio" id="email" name="contact-method" checked>
6
      <label for="email">
7
        <svg>
8
          <use xlink:href="#checkbox_empty"></use>
9
        </svg>
10
        <svg class="checkmark">
11
          <use xlink:href="#checkmark"></use>
12
        </svg>
13
        By Email
14
      </label>
15
    </li>
16
    <li>
17
      <input type="radio" id="phone" name="contact-method">
18
      <label for="phone">
19
        <svg>
20
          <use xlink:href="#checkbox_empty"></use>
21
        </svg>
22
        <svg class="checkmark">
23
          <use xlink:href="#checkmark"></use>
24
        </svg>            
25
        By Phone
26
      </label>
27
    </li>
28
  </ul>       
29
  <svg>
30
    <use xlink:href="#fieldset"></use>
31
  </svg>
32
</fieldset>

Finalmente, el quinto elemento de la lista contendrá los botones para enviar y restablecer junto con sus SVGs:

1
<div class="form-wrapper">
2
  <button type="submit">SUBMIT</button> 
3
  <svg>
4
    <use xlink:href="#button"></use>
5
  </svg>
6
</div>
7
<div class="form-wrapper">
8
  <button type="reset">RESET</button> 
9
  <svg>
10
    <use xlink:href="#button"></use>
11
  </svg>
12
</div>


2. Define algunos estilos básicos

Antes de analizar más a detalle los elementos individuales del formulario, definamos primero algunos estilos básicos de CSS. Entre estos se encontrará una fuente personalizada tomada de Envato Elements, algunas variables personalizadas y algunas reglas de restablecimiento:

SUMMER - FONT PACK
SUMMER - PAQUETE DE FUENTES
1
@font-face {
2
  font-family: "Summer";
3
  src: url(SummerFont-Regular.woff);
4
}
5
6
@font-face {
7
  font-family: "Summer Bold";
8
  src: url(SummerFont-Bold.woff);
9
}
10
11
:root {
12
  --white: #fff;
13
  --red: #e31b23;
14
}
15
16
* {
17
  padding: 0;
18
  margin: 0;
19
  border: none;
20
  box-sizing: border-box;
21
}
22
23
input,
24
textarea,
25
button {
26
  font-family: inherit;
27
  font-size: 100%;
28
  background: none;
29
  outline: none;
30
}
31
32
[type="radio"] {
33
  position: absolute;
34
  left: -9999px;
35
}
36
37
button,
38
label {
39
  cursor: pointer;
40
}
41
42
textarea {
43
  resize: none;
44
}
45
46
ul {
47
  list-style: none;
48
}
49
50
body {
51
  font: 32px/1.2 "Summer";
52
  margin: 1.5rem 0;
53
}

Nota: por simplicidad, no voy a mencionar todas las reglas de CSS en este tutorial. Puedes echar un vistazo al resto haciendo clic en la pestaña CSS del proyecto de demostración.

3. Crea el diseño del formulario

En pantallas pequeñas, todos los elementos de nuestro formulario estarán apilados:

The form layout on small screensThe form layout on small screensThe form layout on small screens
El diseño del formulario en pantallas pequeñas

Sin embargo, en ventanas de 600 píxeles o más de ancho, el diseño del formulario cambiará. De manera más específica:

  • Vamos a acomodar los inputs de las dos primeras filas en dos columnas del mismo ancho.
  • Cada botón cubrirá un tercio del ancho de la fila padre.
The form layout on large screensThe form layout on large screensThe form layout on large screens
El diseño del formulario en pantallas grandes

Gracias al Grid (Cuadrícula) de CSS, podemos construir fácilmente el diseño de múltiples columnas que deseamos. Para empezar, configuraremos el contenedor .handmade-form .grid para que sea un grid. Después, usaremos las clases auxiliares grid-2 y grid-3 para definir la cantidad de columnas del grid:

1
@media screen and (min-width: 600px) {
2
  .handmade-form .grid {
3
    display: grid;
4
    grid-gap: 1.5rem;
5
  }
6
7
  .handmade-form .grid-2 {
8
    grid-template-columns: repeat(2, 1fr);
9
  }
10
11
  .handmade-form .grid-3 {
12
    grid-template-columns: repeat(3, 1fr);
13
  }
14
}

Todas estas reglas se colocan dentro de una consulta de medios, por lo que solo surtirán efecto en ventanas con un ancho de 600px o más.

4. Estiliza los elementos del formulario

Ya teniendo establecida nuestra estructura, nuestro siguiente paso es designar algunos estilos estéticos iniciales para todos los elementos del formulario:

1
/*CUSTOM VARIABLES HERE*/
2
3
.handmade-form input:not([type="radio"]),
4
.handmade-form textarea,
5
.handmade-form button {
6
  width: 100%;
7
}
8
9
.handmade-form input:not([type="radio"]),
10
.handmade-form textarea,
11
.handmade-form fieldset {
12
  padding: 15px;
13
}
14
15
.handmade-form textarea {
16
  height: 200px;
17
  vertical-align: top;
18
}
19
20
.handmade-form legend {
21
  padding-top: 15px;
22
  margin: 0 auto;
23
}
24
25
.handmade-form ::placeholder {
26
  color: inherit;
27
  /*Fix opacity issue on Firefox*/
28
  opacity: 1;
29
}
30
31
.handmade-form button {
32
  font-family: "Summer Bold";
33
  color: var(--white);
34
  padding: 5px 10px;
35
}

Colocando las ilustraciones

La siguiente parte de este ejercicio, que es la más desafiante, es colocar las ilustraciones de acuerdo a sus elementos asociados en el formulario. Para hacer esto, usaremos la propiedad position. Una implementación alternativa podría ser establecer los dibujos como imágenes de fondo. Sin embargo, no soy un gran defensor de esta implementación, porque necesita una manipulación adicional para hacer que las imágenes se adapten a varias pantallas.

Positioning the SVGsPositioning the SVGsPositioning the SVGs

Tomemos nota de nuestro plan:

  • Los SVGs serán elementos con una posición absoluta.
  • Estos se encontrarán en la misma posición que sus controles en el formulario y tendrán las mismas dimensiones. Es por eso que anteriormente establecimos sus valores de preserveAspectRatio en none.
  • Deberemos poder asignar el foco a los controles del formulario, así que les daremos un mayor z-index.

Estos son los estilos que se requieren para este comportamiento:

1
.handmade-form .form-wrapper,
2
.handmade-form input:not([type="radio"]),
3
.handmade-form textarea,
4
.handmade-form button,
5
.handmade-form .checkbox-list label {
6
  position: relative;
7
}
8
9
.handmade-form input:not([type="radio"]),
10
.handmade-form textarea,
11
.handmade-form button,
12
.handmade-form .checkbox-list label {
13
  z-index: 1;
14
}
15
16
.handmade-form .form-wrapper svg {
17
  position: absolute;
18
  top: 0;
19
  left: 0;
20
  width: 100%;
21
  height: 100%;
22
}


5. Crea botones de radio personalizados

Para crear nuestros propios botones de radio personalizados, una vez más vamos a aprovechar la "técnica del truco con las casillas de verificación en CSS".

Si echas un vistazo de nuevo a la sección de marcado, notarás que el elemento fieldset contiene la lista .checkbox-list. Existen dos SVGs dentro de cada etiqueta. La primera describe el estado sin seleccionar del botón de radio asociado, mientras que la otra es el estado seleccionado.

Los botones de radio deben caber en una sola fila, por lo que convertiremos la .checkbox-list en un contenedor flex. Además, los colocaremos en una posición absoluta con respecto a sus etiquetas y les asignaremos dimensiones fijas (20px x 20px).

Cuando un botón de radio cambie su estado, el SVG que describe su estado de selección será animado. Para lograr este efecto, vamos a trabajar con las propiedades stroke-dasharray y stroke-dashoffset que hemos cubierto ampliamente en un tutorial reciente.

Estos son los estilos correspondientes:

1
.handmade-form .checkbox-list {
2
  display: flex;
3
  justify-content: center;
4
}
5
6
.handmade-form .checkbox-list li:not(:last-child) {
7
  margin-right: 50px;
8
}
9
10
.handmade-form .checkbox-list label svg {
11
  top: 50%;
12
  left: -25px;
13
  width: 20px;
14
  height: 20px;
15
  transform: translateY(-50%);
16
}
17
18
.handmade-form .checkbox-list label .checkmark {
19
  stroke-dasharray: 233.69552612304688;
20
  stroke-dashoffset: 233.69552612304688;
21
  transition: stroke-dashoffset 0.5s linear;
22
}
23
24
.handmade-form [type="radio"]:checked + label .checkmark {
25
  stroke-dashoffset: 0;
26
}

Nota: A pesar de que he vinculado las propiedades stroke-* al SVG padre en vez de a su path, el efecto aún funcionará ya que estas propiedades se heredan.

Conclusión

¡Eso es todo, amigos! En este tutorial logramos crear un formulario SVG responsivo hecho a mano desde cero. Espero que este ejercicio te haya ayudado a aprender algo nuevo y te haya inspirado a usarlo en algún proyecto futuro.

Aquí tienes un recordatorio de lo que creamos:

En un futuro tutorial, iremos un paso más adelante y discutiremos cómo hacer que este formulario sea dinámico al incorporarlo en un popular complemento de formularios de contacto de WordPress. ¡Mantente atento!

Como siempre, ¡muchas gracias por leer!

Advertisement
Did you find this post useful?
Want a weekly email summary?
Subscribe below and we’ll send you a weekly email summary of all new Web Design tutorials. Never miss out on learning about the next big thing.
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.