Arquitectura frontend con BEM y SASS

26
@rlucha Arquitectura front-end CSS para proyectos a gran escala

description

Expongo un método para estructurar nuestros proyectos con BEM y SASS.

Transcript of Arquitectura frontend con BEM y SASS

Page 1: Arquitectura frontend con BEM y SASS

@rlucha

Arquitectura front-end CSS para proyectos a gran escala

Page 2: Arquitectura frontend con BEM y SASS

¿Qué es un proyecto a gran escala?Media o larga duración / Requisitos indefinidos / Recursos indefinidos

Page 3: Arquitectura frontend con BEM y SASS

Cambiar el enfoqueFacilidad de mantenimiento

Absorber nuevos requisitos minimizando el impactoIncorporar nuevos recursos al equipo lo más rápidamente posible

Page 4: Arquitectura frontend con BEM y SASS

ModularizaciónSeparar un gran proyecto en pequeñas partes discretas

Independencia de las partes / encapsulamientoReutilización de código / DRY

... similar a la programación OO

Page 5: Arquitectura frontend con BEM y SASS

OOCSSUn objeto CSS es una estructura repetitiva independiente del contexto

Principio de responsabilidad únicaPrincipio open/closed (fácil de extender, difícil de modificar)

Page 6: Arquitectura frontend con BEM y SASS

SMACSSMódulo

ComponenteSubmódulo

Guía de prácticasJerarquía por capas

Es una metodologíaElimina la especificidad

BEMBloque

ElementoModificador

Page 7: Arquitectura frontend con BEM y SASS

Colisión de especificidadLa cascada tiene muchísima potencia pero es difícil de controlar

Una colisión afecta a partes dispares del proyecto

Page 8: Arquitectura frontend con BEM y SASS

Ejemplo

<div class=”contentHolder”>

<ul class=”movieList”>

<li> Item 1</li>

<li> Item 2</li>

<li class=”fav”> Item 3</li>

<li> Item 4</li>

</ul>

</div>

...

<span class=”fav”>

Añadir a favoritos

</span>

· item 1

· item 2

· item 3

· item 4

Añadir a favoritos

.contentHolder .movieList li {

font-size: 10pt;

}

.movieList .fav {

font-weight: 600;

color: #F00;

font-size: 12pt;

}

.fav {

font-size: 14pt;

color: #0F0;

text-decoration: underline;

}

Consecuencias inesperadas

Page 9: Arquitectura frontend con BEM y SASS

BEMBloque

movieList

- --Elementoitem

Modificadorfav

<div class=”contentholder”>

<ul class=”movieList”>

<li class=”movieList-item”> Item 1</li>

<li class=”movieList-item”> Item 2</li>

<li class=”movieList-item movieList-item--fav”> Item 3</li>

<li class=”movieList-item”> Item 4</li>

</ul>

</div>

...

<span class=”fav”>

Añadir a favoritos

</span>

.movieList-item {

font-size: 10pt;

}

.movieList-item--fav {

font-weight: 600;

color: #F00;

font-size: 12pt;

}

.fav {

font-size: 14pt;

color: #0F0;

text-decoration: underline;

}

Page 10: Arquitectura frontend con BEM y SASS

BEM es modular y pseudoespecíficoCreando namespaces locales por módulo/bloque solucionamos los dos

principales problemas de un proyecto a gran escala.

Identificación de las partes y control de la especificidad.

Page 11: Arquitectura frontend con BEM y SASS

BEM + SASS

Podemos utilizar la sintaxis BEM con la anidación de SASS utilizando el operador “&” en conjunción con la directiva @at-root

· & es una referencia al contexto superior· #{&} interpola el nombre del contexto· @at-root crea la regla en el root del documento compilado sin tener en cuenta el nesting

.movieList {

@at-root #{&}-item {

font-size: 10pt;

@at-root #{&}--fav {

font-weight: 600;

color: #F00;

font-size: 12pt;

}

}

}

Page 12: Arquitectura frontend con BEM y SASS

BEM + SASS

&

referencia al contexto superior

#{&}

interpolacióna string

@at-root

añade la regla al root sin nesting

Page 13: Arquitectura frontend con BEM y SASS

Mixins

El uso de mixins abstrae la necesidad deconocer la nomenclatura exacta en SASS

Permite a gente que no conoce SASS extender el proyecto sin curva de aprendizaje

Reduce los errores de sintaxis

No usamos selectores CSS

@include block(movieList) {

@include element(item) {

font-size: 10pt;

@include modifier(fav) {

font-weight: 600;

color: #F00;

font-size: 12pt;

}

}

}

Page 14: Arquitectura frontend con BEM y SASS

Herencia (aka Submódulos)

Al controlar con SASS cómo se interpolan los nombres de clase podemos controlar el contexto en el que se crean las propiedades.

El mixin extendBlock crea la clase .movieList--horizontal .movieList-itemy le aplica inline-block manteniendo el resto de propiedades intactas. Con esta sobrecarga tenemos un control total de la especificidad.

@include block(movieList) {

@include element(item) {

font-size: 10pt;

@include modifier(fav) {

...

}

}

}

@include extendBlock(movieList,horizontal) {

@include element(item) {

display: inline-block;

}

}

.movieList--horizontal .movieList-item

Page 15: Arquitectura frontend con BEM y SASS

BEM.scss

$extend: false;$blockExtended: "";

@mixin block($name) {

@at-root .#{$name} { @content; }

}

@mixin modifier($name) {

@at-root #{&}--#{$name} { @content; }

}

@mixin element($name) {

@if $extend == true {

@at-root #{&} .#{$blockExtended}-#{$name} {

@content;

}

}

@else {

@at-root #{&}-#{$name} {

@content;

}

}

}

@mixin extendBlock($blockExtended,$name) {

$extend: true !global;

$blockExtended: $blockExtended !global;

@at-root .#{$blockExtended}--#{$name} {

@content;

}

$extend: false !global;

}

Page 16: Arquitectura frontend con BEM y SASS

BEM dentro del proyecto

Un archivo scss por bloqueUn archivo template por bloque

Los bloques son específicos del proyecto

/public

/css

/scss/

/vendor

/framework

_base.scss

_variables.scss

_app.scss

/blocks

_movieList.scss

_topNavigation.scss

...

/partials/

movieList.hbs

Page 17: Arquitectura frontend con BEM y SASS

Combinando FMWs

Hacer la transición de frameworks de soluciones a frameworks de componentes.Ofrecen componentes abstraídos de presentación con los que podemos dotar a nuestros bloques de funcionalidades comunes.

· inuit.css· suit.css

/public

/css

/scss/

/vendor

/framework

_base.scss

_variables.scss

_app.scss

/blocks

_movieList.scss

_topNavigation.scss

...

/partials/

movieList.hbs

Page 18: Arquitectura frontend con BEM y SASS

inuit.css

GRID responsiveHeadersSpritesButtons

ListsMedia Object

Pagination...

Page 19: Arquitectura frontend con BEM y SASS

Usando la directiva @extend podemos extender la funcionalidad de nuestros bloques con las abstracciones del framework de componentes

Reutilizamos abstracciones comunes a todos los proyectos

Extendiendo el proyecto

Page 20: Arquitectura frontend con BEM y SASS

@extend %placeholders

@include block(movieList) {

@extend %framework-blockList;

@include element(item) {

@extend %framework-blockList-item;

font-size: 10pt;

@include modifier(fav) {

font-weight: 600;

color: #F00;

font-size: 12pt;

}

}

}

%framework-blockList {

margin: 0;

padding: 0;

list-style: none;

}

%framework-blockList-item {

padding: $fmw-block-list-padding;

}

Page 21: Arquitectura frontend con BEM y SASS

open/close por capas

Scaffolding ( normalize.css, animate.css, ... )

Theme ( pink.scss, ocean.scss, ... )

Blocks ( movieLIst.scss, mainMenu.scss, ... )

@extend

override

@import

Framework ( inuit.scss, suit.scss, ... )

Page 22: Arquitectura frontend con BEM y SASS

Resumenseparar en módulos / identificarlos / encapsularlos / reutilizarlos

scaffolding / extender FMW / integrar módulos / customizar temas

Y después...

Page 23: Arquitectura frontend con BEM y SASS

Testing

.movieList-item {

@extend %error;

}

.movieList .movieList-item {

@extend %success;

}

Partir de un estado de error que sólo se resuelve si se usa en el contexto apropiado

Inyectar CSS desde el navegador con extensiones

Page 24: Arquitectura frontend con BEM y SASS

Generadores estáticosAssemble / Jekyll / DocPad

Page 25: Arquitectura frontend con BEM y SASS

En el futuro...Preprocesadores customizables

Interpolaciones arbitrarias de selectoresNuevas reglas y relaciones

ReWorkShadow DOM

Directivas

@mixin extendBlock($blockExtended,$name) {

$extend: true !global;

$blockExtended: $blockExtended !global;

@at-root .#{$blockExtended}--#{$name} {

@content;

}

$extend: false !global;

}

Page 26: Arquitectura frontend con BEM y SASS

@rlucha

¡Muchas gracias!