edu.css-architecture



edu.css-architecture

1 8


edu.css-architecture

Buenas prácticas en CSS:

On Github nahuelsotelo / edu.css-architecture

Buenas prácticas en CSS

Hola, soy Nahuel Sotelo

Frontend developer en Schibsted Spain y Profesor de la asignatura Programación Frontend en el Master de Diseño Web de Bau.

Contenidos

Introducción Guía de estilos de código Arquitectura de carpetas Componentes modulares Especificidad Selectores Sistemas de Nomenclatura Conclusiones

Introducción

¿Por qué es importante cuidar el código y tener buenas prácticas?

¿Por qué?

  • Trabajar en un equipo de varios developers.
  • Generar un código mantenible y escalable.
  • Reutilizar código.
Incluir y reemplazar miembros de un equipo. Codigo similar en diferentes proyectos Cuando estamos trbajando no pensamos que alguien tendrá que mantener ese codigo o que se añadiran más funcionalidades, pero pasará. Si tenemos fragmentos de codigo reutilizables sin demasiada dependencia a un proyecto en concreto seremos mas rápidos en futuros proyectos. Tampoco hay que pasarse con la abstracción.

¿Cómo?

  • Generando un código organizado, estructurado y bien documentado
  • Fragmentando el código en pequeños trozos (componentes/módulos/objetos) independientes
  • Separando los componentes de su contexto
  • Refactorizando continuamente

Esto nos permitirá trabajar en una parte concreta de nuestra aplicación sin afectar al resto

Enlaces relacionados

Guía de estilos de código

Una guía de estilos:

  • Genera un código más legible y fácil de mantener.
  • Disminuye la cantidad de errores.
  • Refuerza las buenas prácticas.
  • Permite trabajar en un mismo proyecto a desarrolladores de diferente nivel.

Ejemplos:

Estas guías también van muy bien como herramienta de aprendizaje para ver cómo trabaja otra gente.

Existen herramientas que nos ayudarán a que todos los miembros del equipo sigan las pautas definidas.

Arquitectura de carpetas

Es recomendable centralizar los estilos en un ùnico fichero (main.css, style.css) que no contenga reglas, únicamente @import a otros ficheros.

Wallpaper by Julien He

Puede haber más de uno dependiendo las necesidades. Por ejemplo en una guía de estilos, si tenemos soporte para algun navegdor concreto o si tenemos estilos que sólo se cargan en una página.

Comentar sobre HTTP2.

Podemos encontrar varias arquitecturas en internet pero es importante conseguir una que se adapte a las necesidades de nuestro proyecto.

La clave está en tener claro la función de cada selector que utilicemos y ubicarlo en el archivo correspondiente.

Un ejemplo: El patrón 7-1

7 carpetas, 1 archivo:

  sass/
  |
  |– base/
  |   |– _reset.scss
  |   |– _typography.scss
  |   ...
  |
  |– components/
  |   |– _buttons.scss
  |   |– _carousel.scss
  |   |– _cover.scss
  |   |– _dropdown.scss
  |   ...
  |
  |– layout/
  |   |– _navigation.scss
  |   |– _grid.scss
  |   |– _header.scss
  |   |– _footer.scss
  |   |– _sidebar.scss
  |   |– _forms.scss
  |   ...
  |
  |– pages/
  |   |– _home.scss
  |   |– _contact.scss
  |   ...
  |
  |– themes/
  |   |– _theme.scss
  |   |– _admin.scss
  |   ...
  |
  |– utils/
  |   |– _variables.scss
  |   |– _functions.scss
  |   |– _mixins.scss
  |   |– _helpers.scss
  |
  |– vendors/
  |   |– _bootstrap.scss
  |   |– _jquery-ui.scss
  |   ...
  |
  |
  `– main.scss
    
  • base/

    Es el punto de partida del proyecto (reset, tipografía, etc). Los selectores de esta carpeta tendrán una especificidad muy baja, probablemente la mayoría serán selectores de tipo.

  • layout/

    Todo aquello referente al layout de nuestro sitio: grid, header, footer, sidebar, etc. Aquellos componentes que se repiten página a página.

  • components/

    El core de nuestra web. Todos aquellos componentes reutilizables que utilizaremos a lo largo de nuestra web.

  • pages/

    Estilos específicos para una página en concreto.

  • themes/

    Si nuestro sitio tiene algun tipo de sistema de theming, podemos hacer uso de esta carpeta. En caso contrario puede omitirse.

  • utils/

    Variables, funciones, mixins o cualquier otro tipo de helper. Lo normal es que los contenidos de esta carpeta no se compilen en el fichero .css.

  • vendors/

    Estilos que no hemos creado nosotros: librerías como Bootstrap o estilos que acompañen algún plugin que estemos utilizando.

Recomendar el adaptar esta estructura a las necesidades de nuestro proyecto (enfoque Lean).

Comentar la arquitectura que estoy usando ahora (components / utils / vendors).

  @import 'utils/variables';
  @import 'utils/functions';
  @import 'utils/mixins';
  @import 'utils/placeholders';

  @import 'vendors/bootstrap';
  @import 'vendors/jquery-ui';

  @import 'base/reset';
  @import 'base/typography';

  @import 'layout/navigation';
  @import 'layout/grid';
  @import 'layout/header';
  @import 'layout/footer';
  @import 'layout/sidebar';
  @import 'layout/forms';

  @import 'components/buttons';
  @import 'components/carousel';
  @import 'components/cover';
  @import 'components/dropdown';

  @import 'pages/home';
  @import 'pages/contact';

  @import 'themes/theme';
  @import 'themes/admin';
    

Enlaces relacionados:

Componentes modulares

“It's a repeating visual pattern, that can be abstracted into an independent snippet of HTML, CSS and possibly JavaScript.”

- Nicole Sullivan

Características de un componente:

  • Son un fragmento de la interfaz que cumple una única función.
  • Son independientes, tanto de su contexto como del resto de componentes.
  • Son reutilizables.
  • Son autocontenidos, no filtran estilos a otros componentes.

Separados del layout. Su relación con el contexto se gestiona por separado.

El CSS de un componente tiene que tener una logica interna, que debe apreciarse leyendo el código.

Enlaces relacionados:

Especificidad

En CSS, la especificidad, es lo que determina que estilo será el que acabará aplicandose a un elemento determinado.

Cuando a un elemento se le aplica más de un selector con reglas que actúan sobre la misma propiedad, es la especificidad la encargada de resolver este conflicto.

A grandes rasgos podemos ordenar los diferentes tipos de selectores de menor a mayor peso específico de la siguiente manera:

Selectores de elemento Selectores contextuales Clases IDs

Calcular especificidad

0,0,0,0

p {
  color: red;
}

0,0,0,1

.text {
  color: red;
}

0,0,1,0

#main strong {
  color: red;
}

0,1,0,1

header ul#main-nav .sub-menu li.child a:hover {
  color: red;
}

0,1,3,4

<p style="color: red">Lorem ipsum dolor sit amet, consectetur adipisicing elit.</p>

1,0,0,0

p {
  color: red !important;
}

0,0,0,1 0,0,0,0

Enlaces relacionados:

Selectores

Carcterísticas de un buen selector

  • Tiene baja especificidad
  • Es sólido (no depende del contexto)
  • Es autodocumentado (su función se entiende solo con leerlo)

El gráfico de especificidad es una representación de cómo se distribuye la misma a lo largo de una hoja de estilo.

Es recomendable que la especificidad vaya aumentando gradualmente, empezando con estilos más genéricos (selectores de elemento) y acabando con casos más específicos.

Gráfico de especificidad

The Specificity Graph - Harry Roberts

Especificidad plana

Intentar mantener los selectores lo más cortos posibles (evitar nesting) nos ayudará a que nuestros componentes no estén atados a un contexto determinado y sean independientes del HTML.

  /* Cuidado! */
  #main-header nav ul > li .nav-link:first-child { ... }  /* 0, 1, 2, 3 */

  /* Mejor */
  .MainNav-link--first { ... }  /* 0, 0, 1, 0 */
    

Nomenclaturas

"What we want is to be able to write code that is as transparent and self-documenting as possible. Transparency means that it is clear and obvious (to others) in its intent; self-documenting means that we don’t have to lose time to writing and reading lengthy, supplementary documentation." - Harry Roberts

Enlaces relacionados:

Sistemas de Nomenclatura

BEM(block / element / modifier)

  .nombre-del-bloque { ... }

  .nombre-del-bloque__elemento { ... }

  .nombre-del-bloque--modificador { ... }
    

BEM Nesting

    .nombre-del-bloque {
      ...

      &__elemento {
        ...
      }

      &--modificador {
        ...
      }
    }
    
    .nombre-del-bloque { ... }
    .nombre-del-bloque__elemento { ... }
    .nombre-del-bloque--modificador { ... }
    

Refactorizando:

  .tab-group { ... } /* 0, 0, 1, 0 */

  .tab-group > li { ... } /* 0, 0, 1, 1 */

  .tab-group a { ... } /* 0, 0, 1, 1 */

  .tab-group a.selected { ... } /* 0, 0, 2, 1 */
    
  .tab-group { ... } /* 0, 0, 1, 0 */

  .tab-group__tab { ... } /* 0, 0, 1, 0 */

  .tab-group__link { ... } /* 0, 0, 1, 0 */

  .tab-group__link--selected { ... } /* 0, 0, 1, 0 */
    

Otros sistemas nomenclaturas

Cómo continuar

Aprender y adaptar:

Es importante seguir leyendo y mirando los diferentes frameworks o soluciones que va creando la comunidad pero siempre adaptándolos a nuestras necesidades. No al copy-paste.

Practicar:

Aplicar las buenas prácticas siempre que se pueda, la mayoría son universales y no dependen del tamaño o naturaleza del proyecto.

Divide y vencerás:

Intentar repartir nuestro código en pequeños trozos manejables. Evitar los archivos de 2000 líneas.

Documentar:

Dejar nuestro código bien documentado nos ayudará a volver sobre nuestros proyectos pasado un tiempo sin perder la razón, además de ayudar a otros developers que trabajen con el mismo.

Documentar también nos ayuda a reflexionar sobre lo que hemos hecho y fijar conceptos.

Refactor constante:

No tener miedo al refactor siempre y cuando se haga con las precauciones adecuadas. Si hemos seguido buenas prácticas refactorizar no debería ser muy costoso.

¡Grácias!

Buenas prácticas en CSS por Nahuel Sotelo