Un puñadico de links

Tools

https://iconsvg.xyz
Otra coleccion de iconos en svg, lo interesante es que se puede personalizar el trazo y otros factores, y te pone el codigo svg resultante facilitando mucho ponerlo inline.

https://codepen.io/sosuke/pen/Pjoqqp

Este es muy bueno y util, una calculadora de colores con filtros css, le indicas un color y te devuelve los css filter necesarios para conseguirlo a partir de una imagen (o elemento) negro

https://9elements.github.io/fancy-border-radius/
Un editor de border radius de 8 puntos, esta caracteristica no es muy conocida y tiene su juego

Learn

https://cssbattle.dev/

Un sitio donde se propone una imagen y hay que replicarla con la menor cantidad posible de css y html. Cuando digo “menor” es que hasta el ultimo bit cuenta.

https://parametric.press/issue-01/unraveling-the-jpeg/
Muy curioso, explica como funciona la compresion jpg y permite alterar las tripas de un archivo .jpg para ver el resultado en la imagen de forma instantanea

https://medium.com/s/story/technical-debt-is-like-tetris-168f64d8b700
Una explicacion muy interesante de la deuda tecnica a partir del juego tetris. Y como en el tetris, la partida contra la deuda técnica no acaba nunca

UX/UI

https://refactoringui.com/previews/building-your-color-palette/
Es muy facil elegir una paleta de colores chula e igual de facil cagarla aplicandola. Consejos practicos sobre como hacerlo:

Depurando tu CSS con las dev tools de Chrome

En fin, ese css tan hermoso y limpio en origen ha pasado varias guerras, nacimientos y muertes en el DOM y ahora es un empastre inescrutable de miles de lineas donde nadie se atreve a quitar nada.
Pero hay herramientas para ayudarte a ponerlo en vereda.

https://cssstats.com/

graficoespec

Analiza tu css y te devuelve un completo informe con la cantidad de colores, fuentes, gráficos de especificidad, etc. Todas las estadísticas sobre tu CSS necesarias para tener un primer vistazo de la situación y un punto de referencia con el que comparar el trabajo una vez terminado.
Ademas puedes cotillear informes de sitios populares.

Interpretar el gráfico de especificidad daria para articulo completo pero baste saber que debería ser lo mas lo mas plano y bajito posible, señal de que no hay id’s, ni !important’s, ni selectores “largos”, etc.

No obstante, la información de fuentes y colores ya es muy útil para ir localizando código repetido e innecesario,

Ya tenemos unas estadísticas y hay que localizar el css no utilizado. Podemos ayudarnos de la función coverage, del inspector de chrome, nos vamos a la ventana (more tools> coverage)  y pulsamos el botón de iniciar grabación.
Nos aparecerá los CSS y JS de la pagina web con una barra indicando que porcentaje del archivo es usado ademas de otra información. Podemos pinchar sobre el nombre del fichero css para ver su fuente en la ventana sources, donde se nos marca con barras rojas/verdes las clases no usadas/usadas.

Inicialmente se nos marcan en rojo tanto  las clases CSS como las funciones JS que no se utilizan, como algunas dependen de cambios en el DOM, conforme van siendo utilizadas al navegar se van marcando en verde.

clean

Una vez finalizada la navegación, tendremos una primera aproximación de las clases que podemos borrar, podemos hacerlo ahi mismo en la ventana de sources y luego hacer copipaste, o bien usar la funcion overrides para guardar una copia en disco de las ediciones que hacemos.

Para activar overrides nos vamos a su pestaña en la ventana izquierda de sources (es posible que tengamos que pulsar >> para verla) y si es la primera vez que la activamos, nos pedirá un directorio donde almacenar los cambios.

A partir de ahora, podemos hacer los cambios necesarios en el css (como borrar las clases pintadas en rojo por no ser usadas) y al hacer control+s se nos guardará la copia del css en el directorio indicado. Es más, al recargar la pagina, mientras tengamos activado el checkbox de “Enable local overrides” se usara el css guardado en local en vez del css del servidor.

Ojo con esto, no lo dejemos activado sin darnos cuenta al acabar la faena o nos puede confundir. Tenemos alguna ayuda visual para evitarlo, arriba, en el nombre del archivo, nos aparece una bolita morada para indicar que es un archivo sobrescrito en local, y un asterisco si hay cambios sin guardar

Captura de pantalla 2019-02-25 a las 14.12.23

También tendremos un ojo puesto en la ventana computed del inspector, ahí nos indicara cuantas clases estamos chafando en cada elemento, cifra que trataremos de mantener al mínimo.

Una vez limpio el css es buena idea es pasar el CSS a SASS, si es que no lo usamos ya, (que seguro que no, porque si no usar estas herramientas no tendría mucho sentido), para ello tenemos varios servicios en linea como http://sebastianpontow.de/css2compass/ que está muy bien y nos permite bastantes opciones.

Incluso si no fuéramos a utilizar SASS (que deberiamos si o si), nos ayudará a comprender que clases dependen de otras y como están anidadas en el CSSDOM.

Ya tenemos el CSS limpio de clases no usadas y ordenado.  El siguiente paso seria ajustar su nomenclatura con un poco de sentido y coherencia según alguna de las metodologias que hemos visto.

A mi me gusta marcar las clases que dependen de otras al estilo de BEM, pero me encanta usar la herencia, y uso tags semanticos, por lo que no hago una herencia paralela basada en la nomenclatura como exige el sistema, solo tomo de BEM la nomenclatura de clases.

Por ultimo seria conveniente dividirlo  minimamente al estilo de SMACSS en modulos según su función al gusto de cada uno, usualmente yo parto de:  reset (inicializacion y normalize) , composicion (layout y maquetacion, margenes..) y aspecto (colores, fondos, fuentes…).

 

Sistema de templates realizado en Node.js

Este es un sistema sencillo de templates realizado con Node que hice como paso intermedio para adaptar nuestro ecosistema de plantillas a Twig, me permitió ir limpiando código duplicado e identificando bloques de forma rápida. La escribí desde cero y aunque es muy sencilla, funciona realmente bien. Está pensada para trabajar con plantillas php y necesita las siguientes carpetas:

/templates es rellenada automáticamente con las plantillas generadas.

 /sources los archivos de texto con la extensión .tpl que generan las templates
/base  Las plantillas base de las que derivan las demás.
 /mods  los módulos php para trabajar con los bloques

FORMATO DE LAS PLANTILLAS BASE PHP:

Se dividen los bloques de código susceptible de ser modificado con comentarios php con un nombre arbitrario con el siguiente formato (se pueden anidar):

<?php#bloque?> 

    <?php#subbloque?>

    <?php#/subbloque?> 

<?php#/bloque?>
(Los tags de inicio y fin de bloque se borran de las templates .php generadas)
Si fuera necesario usarlos como “ancla” para añadir contenido se pueden poner bloques vacíos donde sea necesario sin problema, o añadir bloques en cualquier momento que surja la necesidad.
Para cada plantilla que queramos crear, se añade un archivo de texto con la extension .tpl en /sources, en la primera linea indicamos la template maestra, en las siguientes, las modificaciones que queremos hacerle.
El motor coge cada cada archivo  sources/*.tpl y lo transforma en un templates/*.php con el mismo nombre, relleno con el código de la plantilla base indicada y modificado con lo que se haya pedido en el archivo tpl.
 
FORMATO DEL ARCHIVO .TPL:
Primera linea>> el nombre (sin la extensión) de la plantilla base
Siguientes líneas>> modificaciones a la plantilla base.
Las modificaciones se indican así: bloque (>|+|-)  modulo, que indican sustituir, añadir o quitar elementos de la plantilla base o de los módulos cargados.
El motor interpreta linea a linea secuencialmente, modificando el código resultado de aplicar la linea anterior, o sea que si en una línea cargamos un módulo, en las siguientes podemos modificar sus bloques cargando nuevos módulos en ellos y así  hasta el infinito (o se acaben las lineas del archivo .tpl, lo primero que ocurra 🙂 ).

Una plantilla podría tener el siguiente contenido:

fr_base //coge la plantilla base/fr_base.php
head > head_orange // cambia el bloque head por el contenido de mods/head_orange.php
main + thumbs  // a continuación  del bloque “main” añade el modulo mods/thumbs.php
boton – //borra el bloque boton, que puede estar en cualquiera de los bloques anteriores

 
Lo que hace la rutina es leer los .tpl, cargar el código del php indicado en la primera linea y a continuación interpreta linea a linea el resto del archivo modificando el código del php en consecuencia. Básicamente lo que hace es buscar con una expresión regular el bloque indicado a la izquierda del operador y sustituirlo o añadir el archivo php indicado  ala derecha, o borrarlo sin mas.
Toda la magia del sistema está en esta Regexp:
RegExp("<\\?php#" + origen + "\\?>((?!<\\?php#\\/\\?>).|\\r\\n|\\r|\\n)*<\\?php#\\/" + origen + "\\?>");

“Origen” es el bloque indicado a la izquierda del operador (>, + o -), con esto seleccionamos el contenido del bloque y el resto es trivial.  Permite mantener los comentarios usuales en los phps porque se limita a buscar comentarios que estén cerrados con “/”

 A continuación, el código.  Son menos de 100 lineas de código y aun se podría optimizar más, aun tiene partes del prototipado, aunque no sé si volveré a el porque ya ha cumplido su cometido, y tampoco era su función complicarse mucho más.
var fs = require('fs');
var glob = require('glob');

compila();

function compila() {
    const util = require('util');
    const glob = util.promisify(require('glob'));
    glob('../cdn.landing.engine/sources/**/*.tpl', function(err, files) {
        files.forEach(function(element) {
            lee_plantilla(element);
        });
    });
}

function lee_plantilla(template) {
    fs.readFile(template, (err, data, isdone) => {
        data = data.toString().replace(" ", "");
        if (data.charAt(data.length - 1) != "\n\n") {
            data += "\n"
        }
        if (data.split(/[\r|\n]+/).length > 1) {
            var index = 0;
            data.split(/[\r|\n]+/).forEach(function(line) {
                index++;
                switch (index) {
                    case 1:
                        codigo = fs.readFileSync("..engine/sources/base/" + line + ".php");
                        break;
                    case data.split(/[\r|\n]+/).length:
                        escribe_php(codigo.toString(), template.split("/").pop())
                        break;
                    default:
                        codigo = interpreta(codigo.toString(), line, template);
                        break;
                }
            })
        } else {
            fs.readFile("../cdn.landing.engine/templates_sources/base/" + data.toString() + ".php", (err, data, isdone) => {
                escribe_php(data.toString(), template.split("/").pop())
            })
        }
    })
}

function escribe_php(contenido, destino) {
    fs.writeFile("../engine/templates/" + destino.replace(".tpl", ".php"), limpiatags(contenido), function(err) {
        console.log("error" + err)
    });
}

function interpreta(codigo, linea, template) {
    if (linea.indexOf('+') > -1) {
        divisor = linea.indexOf('+');
        var operador = "+";
    }
    if (linea.indexOf('>') > -1) {
        divisor = linea.indexOf('>');
        var operador = ">";
    }
    if (linea.indexOf('-') > -1) {
        divisor = linea.indexOf('-');
        var operador = "-";
    }
    var origen = linea.slice(0, divisor);
    var destino = linea.slice(divisor + 1, linea.length);
    var formula = new RegExp("<\\?php#" + origen + "\\?>((?!<\\?php#\\/\\?>).|\\r\\n|\\r|\\n)*<\\?php#\\/" + origen + "\\?>");
    var a = codigo.match(formula).slice(0, -1);
    new_code = fs.readFileSync("../engine/sources/mods/" + destino + ".php");
    switch (operador) {
        case "+":
            return codigo.replace(a, (a + new_code));
            break;
        case ">":
            return codigo.replace(a, new_code);
            break;
        case "-":
            return codigo.replace(a, "");
            break;
    }
}

function limpiatags(codigo) {
    var formula = new RegExp("<\\?php#((?!>).)*\\?>", "g");
    var a = codigo.match(formula);
    if (a) {
            for (var i = 0; i < a.length; i++) {
                codigo = codigo.replace(a[i], "")
            }
    }
     return codigo.replace(/^(?:[\t ]*(?:\r?\n|\r))+/gm, "")
}

Ejemplo de uso de snippets

Los snippets son trozos de código JS que se puede ejecutar sobre cualquier web desde el navegador. Están disponibles tanto en Chrome como en Firefox,  abrimos el inspector y en la pestaña de sources, en la ventana izquierda, veremos la sección de snippets, ahí podemos añadir los que queramos. Nos permiten interactuar con una web automatizando procesos. Para muchas cosas son mas cómodos que las extensiones porque los puedes editar al vuelo y son mas sencillos de aplicar.

A veces los uso para automatizar interacciones con formularios de alguna web, como en el siguiente ejemplo:

Lo que cuento es un poco “irregular”, o sea que pongamos que lo ha hecho un amigo :).

Pues mi amigo necesitaba una base de datos de marcas  y modelos de teléfonos móviles, pero no conseguía encontrar ninguna.
Al final encontró una web con dos selectores, uno de marcas y otro de modelos que se actualizaba automáticamente al elegir una marca mediante una llamada php.

¿Como extraer la información? Pues con un becario que fuera copiando ambos resultados.
Pero como no había becario a mano tuvo que utilizar un snippet.

Este es el código que usamos, simplemente se pega y haciendo botón derecho > run o desde el boton de la parte inferior de la ventana de codigo  lo ejecutamos:

index = 1; 
//aqui almacenaremos los datos
datajson = {}; 
//contamos las marcas del selector
cuantos = $("#selector_marcas").size();
copia(); 

function copia() {
     //seleccionamos la primera marca
    document.getElementById("selector_marcas").selectedIndex = index; 
    //lanzamos un evento change para que se rellene el selector de modelos y ponemos un retardo para dar tiempo a que se rellene...
    $("#selector_marcas").change();
    setTimeout(function() {   
    datajson[$("#selector_marcas").val()] = [];
    // y lo rellenamos con las opciones del selector de modelos
    $("#selector_modelos option").each(function() {
        datajson[$("#selector_marcas").val()].push($(this).val()) 
    });
    //borramos el primer dato del array, que contiene el texto "elige modelo"
    datajson[$("#selector_marcas").val()].splice(0, 1);
    console.log(index + " de " + cuantos);
    if (index < cuantos) {
        index++;  
        copia();
    } else {
         //convertimos el objeto en una cadena de texto y la sacamos por consola
        console.log(JSON.stringify(datajson))
    }
    }, 1000); 
}

Cuando acaba podemos hacer botón derecho sobre la consola y “copiar” para pegar el json en un archivo de texto.

Trabajando con Node.js

He empezado a profundizar con Node, que hasta ahora no lo usaba más que como un entorno donde correr Gulp y poco más. Y, despues del tiempo pasado con Angular, es como volver a casa.
Es muy sencillo y usa the-old-good JS de toda la vida sin más problemas ni lios. Las dependencias se inyectan de forma muy sencilla y puedes tener toda una aplicación en un solo archivo si no es necesario más.  No necesitas cientos de archivos de configuracion para cada pijada que hagas como en Angular (aunque sé que no son comparables).

De repente ya no quiero tanto a Gulp, me he dado cuenta de que casi todo para lo que usaba Gulp lo puedo hacer usando Node y usando  los módulos NPM directamente sin esperar a que alguien los adapten a Gulp o  mantengan actualizados.
Por ejemplo para automatizar los pantallazos de testing la única herramienta que he encontrado en Gulp usa PhantomJs, que es un proyecto abandonado y emplea un motor de render webkit con 10 años que ni siquiera acepta Flex. Sin embargo, usando Node directamente, puedo escribir un script que use Puppeteer y renderice con Chrome headless, compare produccion y stagging y me guarde pantallazos con los errores marcados en una carpeta.

Conforme más aprendo de Node menos uso Gulp y creo que en breve lo utilizare solo residualmente.

Aunque hasta el momento solo lo estoy usando como motor de script,  empiezo a experimentar con servidores y es una verdadera gozada poder hacer un back-end sin salir de javascript, con las herramientas que antes estaban vetadas ejecutando en el cliente, como escribir archivos, manipular bases de datos, etc. que hasta ahora necesitaban scripts intermedios en php.

Como bonus, es el lenguaje que utilizan las placas Arduino, con lo que si un dia me decido por fin a construir un ejercito de robots para destruir el mundo ya tengo parte del camino hecho.

En fin, que mola mucho.

Casi me CSS saltan las lagrimas…

Al leer algo así, en este mundo tan atomizado, loco y maravillosamente confuso que se ha vuelto el front-end donde cada uno se inventa su propio sistema que será “el futuro de la web” reinventando la rueda.

This approach makes me a dinosaur rebel

My approach to front end engineering (I use “engineering” here because we’re talking about the structure and loading strategy, not just the code) is, to some, old fashioned.

I use link and script elements to load my CSS and JavaScript. I’m not using frameworks or large libraries. I have no dependencies. I’m not doing any complicated bundling or package management.

It’s 100% Boring Web.

But… it also makes my websites fast as hell and way more fault-tolerant.

I don’t have to worry about a failed or missed dependency breaking my code. I worry less about browser timeouts on my files, because they’re small and cached. I don’t have to mess around with complicated build and load processes.

I can open a text editor and build an app.

A lean, boring web is better for users. And, I’d argue, it’s better for you as a developer.

Este tio es muy interesante, mas cosas chulas:
https://gomakethings.com/my-biggest-challenge-with-javascript/

https://gomakethings.com/whats-wrong-with-css-in-js/

Extension para chrome, Fast Template

He desarrollado una extensión para Chrome para probar el sistema de extensiones de este navegador, que cuando le coges el tranquillo es bastante facil.

Podemos colocar el código en el botón (habitualmente background.js). No tiene acceso al DOM y puede hacer cosas como abrir nuevas ventanas y cosas así. Se puede limitar a ciertas urls a base de filtros. En esta extensión no se utiliza.
También podemos asociar el código al contenido (content.js). Este código si que tiene acceso al DOM y puede interactuar con la pagina, manipularla, etc.

Y podemos asociar un html para que se abra al pulsar el botón de la extensión tipo popup, donde podemos cargar los .js que necesitemos. El ámbito de este js es el del background, por lo que no podemos acceder al DOM, pero podemos hacer llamadas a content.js para que ejecute las acciones necesarias.

Extensión Fast Template

Captura de pantalla 2018-05-27 a la(s) 12.30.31

Lo que hace esta extensión es insertar plantillas en Gmail de forma sencilla  y rápida.  Tenemos un selector de plantillas y un botón para rellenar el mail.
Escribimos lo que sea en el mail y la extensión lo rellena sustituyendo los “#” de la plantilla por dicho texto. Podemos por ejemplo preparar una peticion de trabajo y escribir en el mail solo el nombre de la empresa antes de pulsar “Fill”.
Podemos borrar las plantillas, editarlas o crear nuevas.

Está aun verde y próximamente añadiré cosas como un validador de plantillas, guardado automático , funcionamiento en cualquier formulario, etc.

Podeis descargarla en:
https://github.com/jorgeblancodeveloper/Fastemplate

Entrais en la pagina de extensiones navegando a chrome://extensions/  activais el modo de desarrollador y arrastrais la carpeta de github.

 

Metodologías CSS (3): Atomic CSS

¿Atomic?

“Atomic” a secas no, mejor  “Atomic css” para no confundirse, porque existe otra metodología que se llama “Atomic Design” que no tiene nada que ver. O “Functional css” como se la llama también.

¿Y de que va esta vez?

Es el anticristo del css. su misión es destruirlo , pero no como BEM que solo lo mutila (cortandole la herencia y la especificidad), sino completamente. De hecho, en su ultima evolución, no usa archivos de hojas de estilo  propiamente dichas

¿Mande?

Todo el estilo se hace desde el html con clases que se generan dinámicamente con un procesador. Básicamente, es volver a los 90, cuando se ponia todo en el html, y se hacia  aquello de
<font face="verdana" color="red" size="3">Old school!</font>

Atomic es talibán del mandamiento “Cuanto más pequeño, mas reutilizable”  Funciona solo con clases reutilizables mínimas (atómicas), cada una de ellas preferiblemente con una sola propiedad y, en su variedad “programatic”  se generan al vuelo siguiendo unas convenciones.

Escribimos en el html:

<div class="Bgc(#0280ae) C(#fff) P(20px)">
 Y el procesador nos genera una hoja de estilos tal que así:
.Bgc\(#0280ae\) { background-color: #0280ae; }
.C\(#fff\) { color: #fff; }
.P\(20px\) { padding: 20px; }
 (Nota para novatos: lo de la barra \ es un caracter de escape, se usa para poder usar caracteres prohibidos en los nombres de clase)

Una de las ventajas es que no se tienen nunca clases sin utilizar en el css. Pero porque realmente no se tiene ni siquiera un css, muerto el perro acabo la rabia.

De hecho nunca editamos el css, un procesador va recorriendo el html y creando un css con las clases que se va encontrando.

Echadle un ojo a la referencia de uno de los frameworks que siguen este sistema:
https://acss.io/reference

Básicamente, han convertido cada propiedad de css en una especie de función.

Algunas ventajas que se aducen son:

  • que no hay que escribir una nueva regla con cada pequeño cambio css,
  • que es muy predecible
  • que es facil de leer ya que solo mirando el codigo html se sabe lo que hacen las clases
  • que las clases nunca dependen del contexto, la ventaja habitual de que se pueden mover unos módulos de una parte a otra o reutilizar hojas de estilo en diversos sitios.

Algunas de estas cosas son muy discutibles…

Algunos frameworks para usar este concepto tienen su cachondeo en el nombre como quarks.js, tachyons, etc. (son partículas subatomicas)

Por ejemplo quark.js propone trabajar así:

<div class="color-red fontSize-20"></div>
Realmente, hay muy poca diferencia con ponerlo todo en estilos inline.

¿y a ti te mola? 

No.  Es rarísimo, y va en contra de los principios morales de occidente en cuestión de css, de hecho el artículo que dio pie al concepto se llamaba:   “Desafiando las buenas practicas css”.
En las blasfemas palabras de su autor:

“Preferimos contaminar el html que el css”

Pero algo tendrá el agua cuando la bendicen, esto es (o era) usado por sitios como yahoo.

Como siempre es cuestión de balance y compromiso, ok, vas a hacer las hojas de estilo mas fáciles de mantener pero a cambio de embrollar el html.

Y situaciones donde sea aplicable.
Por ejemplo ninguno de estos sistemas que proponen añadir clases para cambiar el aspecto en vez de usarlas para localizar los elementos (añadiendo .float_right o similar en vez de hacer header >h1{float:right, por ejemplo ) serian fáciles de aplicar en un blog wordpress

Un case study de un hombre que pasó de BEM a atomic y explica por que y como:
https://hackernoon.com/full-re-write-with-tachyons-and-functional-css-a-case-study-part-1-635ccb5fb00b

Metodologias CSS (2): Smacss

¿Otra?

No se si llamarla “otra”, porque es compatible con BEM y pueden trabajar juntas. BEM es más un sistema de nomenclatura (y uso) para evitar problemas de especificidad y herencia  y Smacss es un sistema organizativo de las propias hojas de estilo para facilitar el escalar proyectos, es un poco mas antigua.

¿Y de que va?

La base de Smacss es separar las clases css por su funcionalidad según las siguientes categorías:Base: Podriamos entenderlo como un reset ampliado. Aquí se definen solo los tags, sin clases ni id´s.

Layout: Aquí va todo lo referente a la estructura de la pagina, las secciones, etc.

Module: Partes reutilizables de la web cuyo css debería ser escrito pensando en su independencia.

State: Todas las propiedades relativas a estados, desplegado, activo, apagado, colapsado, etc.

Theme: Unicamente el aspecto visual, fuentes, colores., etc.

Es un esquema flexible, una web podría no necesitar un theme, o podría necesitar un .scss añadido (fonts.scss por ejemplo) si necesitara retoques según el idioma elegido.
Idealmente, estas partes deberían estar en archivos independientes, con los antiguos import de css esto penalizaría la carga pero con sass no hay problemas.

¿Como se escribe?

El autor no pontifica ni se mete mucho con ese tema,  sino que aconseja usar prefijos para las distintas partes, él usa los prefijos .l- para layout, .is- para los estados (que tiene mucho sentido: .is-active) etc.
Las partes relacionadas con un modulo usaran su nombre como prefijo para saber a cual hay que aplicarlas: .example-header
Además, hace hincapié en reducir la “profundidad de aplicación”, esto es, que las clases no dependan de una estructura html determinada.
En este ejemplo:

body.article > #main > #content > #intro > p > strong { }

Vemos una profundidad de aplicación de 6 niveles (aunque hicieramos “.article strong” serian los mismos niveles) cuanta menor sea la profundidad, menos dependerá de una estructura determinada y mas fácil sera mover elementos de una parte a otra. Esto llevado al extremo seria usar las clases directamente, sin herencia, y nos acercariamos a BEM…

Por ejemplo esto tambien seria caca para Smacss:

#sidebar div h3

Porque necesita una estructura determinada y lo correcto seria algo como

.modulo h3

No importa tener que añadir mas clases al html si es para aumentar la flexibilidad.

Vale, quiere reducir la herencia al mínimo ¿y que opina de la especificidad?

Pongamos que tenemos esto:

.pod {
 width: 100%;
 }
 .pod input[type=text] {
 width: 50%;
 }

Y necesitamos que cuando esté en un #sidebar el ancho  del input sea de 100%. Lo primero que nos pide el cuerpo es añadir un selector padre así:

#sidebar .pod input[type=text] {
width: 100%;
}
 Smacss dice “¡No! ¡Caca! ¡Frontender malo!”
Eso añade especificidad al input, si necesitaramos reutilizar la clase .pod dentro de un sidebar con un nuevo ancho de su input, de nuevo habrá que superar la especificidad que hemos puesto añadiendo un selector mas o metiendo un temido !important.
Para evitarlo Smacss propone añadir una nueva clase derivada de .pod (smacss las llama subclases) quedaria así.
.pod {
 width: 100%;
 }
 .pod-short input[type=text] {
 width: 50%;
 }
.pod-callout {
 width: 200px;
 }
 .pod-callout input[type=text] {
 width: 180px;
 }

Y se aplicarian así:

<div class="pod pod-short">...</div>
<div class="pod pod-callout">...</div>

Recordemos que BEM supera los problemas de especificidad usando solamente clases y nunca usando selectores, así, todas las clases se encuentran al mismo nivel y deja de existir la especificidad, una clase machaca a la anterior y chimpun.

 ¿Y a ti te mola?

Si. Esta muy bien lo de separar las clases por su funcionalidad.
Pero me rechina un poco cuando habla de añadir clases para conseguir diseños, y de nuevo, habla de problemas que pueden o no pueden serlo, o pueden resolverse de otras maneras.
Por ejemplo para evitar ligar demasiado el css a una estructura html propone añadir clases, y esa es otra forma de ligar html y css y me genera dudas…
Igual  puedes tener que rediseñar un blog con unos contenidos que ya tienen una maquetación determinada y no puedes añadir clases…
Por ejemplo no es lo mismo cuando el front end developer tiene libre acceso a las plantillas html para poner y quitar clases  que cuando no se tiene acceso (o es limitado) al código.

¿Donde saber más?

El librito del autor está en:

Se lee rápido y hay muchas cosas interesantes.

Metodologias CSS(1) BEM

BEM ¿Que es eso?

Es una metodología de nomenclatura css.
Propone nombrar las clases así: Bloque__Elemento–Modificador.

Bloques serian porciones de la pagina con un contenido y/o uso diferenciado (como un menú) , elementos los elementos de un bloque (como un botón de menú) y modificadores aquellos aspectos que cambian el diseño de un elemento o bloque (como desactivar un botón).

Por ejemplo:
.contact__button–disabled
.contact__button
.header__logo–orange

¿Por que usa dos guiones?

Para distinguir que partes forman parte de la nomenclatura Bloque__Elemento–Modificador y que partes no, como por ejemplo:

.contact__button–disabled-big

¿Por que alterna guion medio y bajo?

Para distinguir los modificadores de los elementos cuando se apliquen a un bloque, así por ejemplo vemos que disabled es un modificador y no un elemento

.contact–disabled

Pero… ¿no seria mejor poner “header .logo.orange” por ejemplo y aprovechar la herencia?

No, BEM dice que no.
Dice que la herencia es mala, caca, porque es impredecible causa muchos problemas y mejor no usarla.

Pe-pe-pe-…pero ¡Mi amada herencia! ¡La primera C de CSS es de cascada por la herencia! ¡Estais matando CSS!

Si.
BEM dice que la herencia impide reutilizar bloques de una parte a otra, y que gran parte del trabajo de css es resetear y sobreescribir valores heredados. Ademas confiar en la herencia complica el trabajo cuando varios developers trabajan sobre el mismo proyecto.
BEM propone eliminar la herencia por completo y definir cada elemento por separado, y no utilizar tags en los css, solo clases.

¿Y no será un coñazo tener que andar reescribiendo lo mismo en cada elemento de cada bloque?

No si usas sass.
Con sass puedes replicar la herencia natural de css a una herencia de archivo fuente sass, ya que puedes escribir el código una sola vez y reutilizarlo con includes y extends.
.header__navigation { 
background: #008cba; 
padding: 1rem 0; 
margin: 2rem 0; 
text-transform: uppercase; 

.header__navigation–secondary { 
@extend .header__navigation;
background: #dfe0e0; 
}

Esto llenara de morralla el css, y los htmls serán kilometricos con clases tan largas…

Bueno, a BEM le da igual, según él compensa por las ventajas que trae.

¿Cuales?

Las derivadas de que cada clase sea totalmente independiente, sobre todo, poder reutilizar elementos sin preocuparse de que hereden valores según se pongan en una parte u otra de la pagina. En proyectos grandes (y/o con varios diseñadores) facilita tener un control del diseño, es más predecible.

¿Y a tí te gusta?

En principio no. A mi me gusta la herencia, los tags semanticos de html5, el viejo buen CSS que nos enseñaron nuestros antepasados.

Es una metodología como hay otras, y no hay una mejor que otra, hay usos mejores que otros, la DRY por ejemplo propone prácticamente lo contrario.
Y cada una tiene sus ventajas e inconvenientes. La herencia nos ha dado mucho y satanizarla está feo.

En la mayoría de sitios donde me he informado, ponían ejemplos de problemas provocados por la herencia que parecían de teletienda, y en realidad se podrían haber solucionado con una planificación correcta del css y un uso inteligente de la herencia sin necesidad de hiperdefinirlo todo con BEM.

Pero claro, a uno se le revuelven las tripas cuando le proponen renunciar a algo como la herencia de CSS, aunque luego lo vas pensando….y te puede pasar como a este hombre

 

 

Y es que tiene cosas positivas, por ejemplo separar la jerarquía de diseño de la jerarquía de la estructura del html.

Con CSS “tradicional”, uno aprovecha la herencia “de localización” en la pagina, la anidación del css es un reflejo de la anidación en el html.
Si un elemento hereda unas propiedades es porque esta fisicamente dentro del otro elemento

El li que está dentro de nav que está dentro de header:
header > nav > li

Con BEM se sustituye por una anidación “de diseño” y ya no importa donde se localice en la pagina sino que se hace una pseudoherencia con el sistema de nomenclatura de la clase.
Podríamos sacar un botón del navegador por cualquier motivo y seguiría estando clara su pseudoherencia y seguiria funcionando:

El boton que pertenece al navegador:
navegador__boton–activo

Normalmente, es correcto que la estructura de anidación del  css refleje la del html pero no tiene porque hacerlo siempre.

Puedo imaginar que es muy útil cuando hay varios diseñadores trabajando en un proyecto grande donde la herencia da mas problemas que soluciones, también creo que es mas fácil aprovechar la herencia en un proyecto mas pequeño o liderado por una sola persona.

Y también puedo imaginar un mundo alternativo  horrible donde la herencia no existe en los css, los archivos se llaman “.ss”  y el ultimo grito es una librería que la añade  (Cascade.js).

Supongo que como de costumbre, en un mundo tan atomizado como el del html, lo bueno sera quedarse con lo que interese y desarrollar sistemas mixtos adaptados a lo que necesitemos.