Atomic Design: La historia de cómo el diseño y el mundo Front empezaron a entenderse.

Desde el nacimiento de la web a manos de Tim Berners Lee hace ya casi 30 años, el diseño y el desarrollo web han ido evolucionando de la mano, pero ¿realmente hemos llegado a comprendernos?

Con el paradigma de Atomic Design surge un enfoque que aúna principios de diseño y front en un ecosistema definitivo.

 

Los comienzos de la web

 

Para analizar todo este mundo, lo mejor es partir del origen, y ese no es otro que el origen de la web.

A principios de los noventa surgió el primer lenguaje para publicación de la Web: HTML. En aquellos tiempos, las páginas web eran muy básicas y su contenido se limitaba a texto plano, pero cumplían con el objetivo para el que fueron creadas: Compartir información a cualquier parte del mundo de manera sencilla.

Años más tarde, con la incorporación de las Interfaces Gráficas de Usuario y la tecnología Flash, el diseño web empezó a obtener relevancia, apoyado en la novedad de poder de añadir imágenes, iconos y tablas, así como visualizar videos, escuchar música o reproducir animaciones en el navegador.

Ya a mediados de 2010 surge un nuevo enfoque para la web: El diseño responsive. Esta manera de plantear la web era consecuencia de una tendencia de uso que comenzaba a acentuarse: la navegación a través de dispositivos móviles.

Desde entonces, las páginas webs han ido evolucionando hacia sistemas adaptables, apoyados en una buena compenetración diseño-desarrollo que ha dado consistencia a la web en los distintos dispositivos y han permitido una experiencia de usuario diferencial.

 

Design System

 

Toda esa evolución derivó en el nacimiento de “design system”, una forma de trabajo que permite evolucionar una web de manera ordenada, eficiente y consistente. Se basa en una herramienta colaborativa conformada por componentes reutilizables y guiada por estándares.

Sus ventajas son muchas: calidad, reutilización, escalabilidad, reducción de la curva de esfuerzo según avanza el tiempo…

En pocas palabras, nos permiten transformar la inconsistencia y el caos en armonía y fluidez.

 

Atomic Design, orígenes

 

En base a este concepto, surge lo que hoy conocemos como “Atomic Design”, cuya premisa es “No diseñamos páginas, diseñamos sistemas de componentes”.

Aunque el paradigma de Design System se acerca a lo que persigue Atomic Design, el diseño atómico deja a un lado colores, tipografías, tamaños de fuente o grids para centrarse en algo más metodológico: Como construir nuestro sistema de componentes.

El enfoque de Atomic Design no era nuevo, pero la inspiración de Brad Frost en organismos químicos hizo que su asimilación en la comunidad fuera rápida y extendida.

 

¿En qué consiste el Atomic Design?

Atomic design es una forma de crear un design system basada en 5 niveles distintos:

Fuente: https://bradfrost.com/blog/post/atomic-web-design/

 

Átomos

 

Los átomos, como su propia definición indica, son “la unidad constituyente más pequeña”. Habitualmente no suelen aportar funcionalidad por si solos, pero son piezas con cierta entidad que utilizaremos para componer entes más complejos.

 

Moléculas

 

Con la combinación de átomos surgen las moléculas, que son las piezas fundamentales de nuestras composiciones. Forman el esqueleto de nuestro Design System.

 

Organismos

 

Los organismos asimilan la complejidad de nuestro sistema de diseño en componentes que acoplan nuestros bloques de moléculas.

 

Plantillas

 

Llegados a este punto, rompemos la analogía química para definir una pieza que da sentido a lo que será nuestro resultado final. Las plantillas conforman secciones de lo que serán nuestras páginas.

 

Páginas

 

Nuestro resultado final. Combinan todos los elementos anteriores para dar la funcionalidad y usabilidad que nuestro usuario necesite en cada caso.

 

Ejemplo de uso

 

Pero entender esta estructura, que mejor que ver un ejemplo real, basado en (como no podía ser de otra forma) Web Components, más concretamente StencilJS:

 

Partimos de un componente atómico: Un botón.

 

import { Component, Prop, h } from '@stencil/core';
@Component({
    tag: 'ui-button',
    shadow: true
})
export class UiButton {
    /** Valor que permite habilitar o deshabilitar el botón */
    @Prop() disabled?: boolean;

    /**  Valor que permite indicar el tipo de botón  */
    @Prop() type?: string;

    render() {
        return (
            <div>
                <button disabled={this.disabled} type={this.type}>
                    <slot name="icon-left" />
                    <slot name="text" />
                    <slot name="icon-right" />
                </button>
            </div>
        );
    }
}

 

Con este botón, y apoyándonos en slots , constituimos un elemento con contenido.

 

import { Component, Prop, Host, h, Watch, State } from '@stencil/core';
@Component({
    tag: 'ui-product-information',
    shadow: true
})
export class UiProductInformation {

    /** 
     * Propiedad no primitiva (Objeto, Array) que contiene la información del producto. 
     * Requiere un watch que parsee a un State interno para usarse 
    */
    @Prop() literals: string;
    @Watch("literals") parseLiterals(newLiterals: string) {
        if (newLiterals) {
            try {
                this._literals = JSON.parse(newLiterals);
            } catch (e) { }
        }
    }
    @State() _literals: { [key: string]: any };

    componentWillLoad() {
        this.parseLiterals(this.literals);
    }

    render() {
        return (
            <Host>
                <div>
                    <slot name="title" />
                    <slot name="subtitle" />
                    {this._literals.map(res => (
                        <div class="cdk-description">
                            <i class={res?.icon}></i>
                            <span class="cdk-description__text">{res?.body}</span>
                        </div>
                    ))}
                    <div class="cdk-inf">
                        <slot name="pricetext" />
                        <slot name="pricenumber" />
                    </div>
                    <div class="cdk-footer">
                        <slot name="linkright" />
                    </div>
                </div>
            </Host>
        );
    }
}

 

Combinando los dos elementos anteriores, constituimos una cabecera:

 

import { Component, Prop, Host, h } from '@stencil/core';
@Component({
    tag: 'cdk-dual-header',
    shadow: true
})
export class CDKDualHeader {

    /** Valor del color del fondo del componente */
    @Prop() backgroundColorDecorator: string;

    /** Ruta de la imagen de fondo */
    @Prop() bgImage: string = '';

    render() {
        const image = { 'background-image': `url(${this.bgImage})` }

        return (
            <Host style={{
                'background-color': this.backgroundColorDecorator
             }}>
                <div class="cdk-container">
                    <div class="cdk-img" style={image}></div>
                    <div class="cdk-body"><slot name="cdk-body-containt" /></div>
                </div>
            </Host>
        );
    }
}


El resultado final podemos verlo aquí:


 

Conclusión

 

Combinando los principios del Atomic Design y el estándar cada vez más asentado de los webcomponents, podemos definir un sistema de componentes que alinea diseño y desarrollo y aporta una oferta de valor diferencial a la hora de crear grandes webs.

Con la flexibilidad como aliada, desarrollar un buen sistema de componentes nos va a permitir tener combinaciones infinitas sin necesidad de implementar una línea de código más, posibilitando crear, componer y modificar tantas páginas como se necesiten.