Upload
roberto-lucha-sedeno
View
903
Download
0
Embed Size (px)
DESCRIPTION
Expongo un método para estructurar nuestros proyectos con BEM y SASS.
Citation preview
@rlucha
Arquitectura front-end CSS para proyectos a gran escala
¿Qué es un proyecto a gran escala?Media o larga duración / Requisitos indefinidos / Recursos indefinidos
Cambiar el enfoqueFacilidad de mantenimiento
Absorber nuevos requisitos minimizando el impactoIncorporar nuevos recursos al equipo lo más rápidamente posible
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
OOCSSUn objeto CSS es una estructura repetitiva independiente del contexto
Principio de responsabilidad únicaPrincipio open/closed (fácil de extender, difícil de modificar)
SMACSSMódulo
ComponenteSubmódulo
Guía de prácticasJerarquía por capas
Es una metodologíaElimina la especificidad
BEMBloque
ElementoModificador
Colisión de especificidadLa cascada tiene muchísima potencia pero es difícil de controlar
Una colisión afecta a partes dispares del proyecto
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
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;
}
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.
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;
}
}
}
BEM + SASS
&
referencia al contexto superior
#{&}
interpolacióna string
@at-root
añade la regla al root sin nesting
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;
}
}
}
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
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;
}
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
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
inuit.css
GRID responsiveHeadersSpritesButtons
ListsMedia Object
Pagination...
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
@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;
}
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, ... )
Resumenseparar en módulos / identificarlos / encapsularlos / reutilizarlos
scaffolding / extender FMW / integrar módulos / customizar temas
Y después...
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
Generadores estáticosAssemble / Jekyll / DocPad
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;
}
@rlucha
¡Muchas gracias!