Usando nomenclatura para aplicar estilos

Todos sabemos como usar los atributos para aplicar distintos estilos, marcar los links que van a determinado sitio, los que van a  abrir una nueva ventana/pestaña, añadir un icono a los links que apunten a un .pdf… (([href*=”wikipedia.com”], [target*=”_blank”], [href $=”.zip”]…)) Se puede leer el origen, el alt, el title, el target, los data-, etc.

Tambien podemos usarlos para marcar de manera arbitraria ciertos contenidos sin necesidad de usar clases ni JS. Por ejemplo un widget de wordpress que permita añadir enlaces, pero no marcarlos arbitrariamente,  tal vez no tienes acceso al codigo (o ni siquiera sabes php)

Puedes marcar esos links añadiendo un target “dummy” al final de la url, puede bastar un simple # vacío, normalmente será ignorado  en la web de destino (a menos que la url necesite un id target) pero nos permite aplicarles estilo con  a[href $=”#”]. En este ejemplo tambien uso content(attr(href) ) para poner como subrayado el propio href del enlace.

Pongamos que quieres o necesitas, por el motivo que sea, usar las mismas imagenes tanto en  horizontal (desktop) como en vertical (phone), y lo apañas con objet-fit:cover y object-position:center , o bien usando sus equivalentes de background-image y background-position si necesitas dar soporte a Explorer y browsers antiguos, para el caso es lo mismo.

Y te encuentras con el problema de que ciertas imágenes tienen el punto de interés desplazado a un lado y lo pierdes en móvil, o en la parte superior y se pierde en desktop. Resulta que le estas cortando la cabeza a esa modelo tan guapa de la tercera imagen de tu slide.

Podrías arreglarlo aplicándoles una clase especial a esas imágenes lo que te obligaría en la mayoría de los casos a añadir un campo nuevo en tu gestor de contenidos para aplicarla, si es que tienes la posibilidad de hacerlo, que a lo mejor ni siquiera tienes acceso por ser una libreria externa.
Tampoco puedes hacer algo como .slide li:nth-child(3) porque te dejaria de funcionar al borrar o insertar una nueva imagen, o si se aplica un random al orden de slides.
Bueno, pues no hace no hace falta usar clases especificas, puedes señalar esas imágenes utilizando su propio nombre para identificarlas utilizando el lector de atributos de CSS.
Con suerte, tu gestor de contenidos permitira añadirle un “alt text” donde podemos colocar nuestras “falsas clases” y leerlas con [alt~=”any”],.
Pero en cualquier caso, podemos añadirlas al nombre de la imagen y leerlas con
 [src*= “”]  , con este selector podemos identificar cadenas de texto inscritas en el nombre (en la ruta, en la realidad) de la imagen. En concreto, el operador * lo que hace es buscar la cadena citada en cualquier lugar del atributo, también podemos añadir más precisión usando otros operadores como ^, $, |… que buscan la cadena al inicio, al final, como cadena completa, etc. tenéis la lista completa y mas información en el link anterior. Para la mayoría de los casos con * es suficiente.

Por ejemplo  en una imagen horizontal con el punto de interés a un lado  podemos añadir los sufijos  @left  o @right (u otros) en el nombre de la imagen y al mostrarla en vertical  identificarla en el css y posicionarla en consecuencia:

img {
  object-position:center center;
}
img[src*="@right"] {
  object-position: right center;
}
img[src*="@left"] {
object-position:left center ;
}

Una solución limpia y sencilla como deben ser siempre en CSS y que no complican nuestra base de datos. La imagen de la chica que mencionabamos antes ahora acaba en @top y se muestra correctamente en desktop.

Podemos combinar propiedades con variables CSS de esta manera

.screen img{
 width:100%;
 height:100%;
 object-fit:cover;
 --originx: center;
 --originy: center;
 object-position:var(--originx) var(--originy);
}
.screen img[src *= "@r"]{
 --originx: right;
}
.screen img[src *= "@l"]{
 --originx: left;
}
.screen img[src *= "@t"]{
 --originy: top;
}
.screen img[src *= "@b"]{
 --originy: bottom;
}

Así podríamos hacer algo como imagen@l@t.jpg para localizar puntos de interés en las esquinas.
Ejemplito en codepen:

Podemos marcar imagenes “en origen” para aplicar variaciones de composicion en logos con una relacion de apecto demasiado extrema en un directorio de empresas, por ejemplo, o en definitiva cualquier ocasion donde no podamos añadir clases arbitrariamente  pero podamos editar el contenido.

No es la solucion mas bonita del mundo pero es un recurso para casos extremos.

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.

 

Clox, reloj de boxeo, PWA

Para jugar con ciertos conceptos de UX/UI estoy haciendo una Progressive Web App, adaptando una App para android que hice hace tiempo, un reloj de boxeo.

Se puede instalar y utilizar 100% sin conexión.

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

Podeis probarla en
https://jorgeblancodeveloper.github.io/clox/
,mejor desde un móvil, y el código fuente en:
https://github.com/jorgeblancodeveloper

Todavia no esta acabada ni lista para producción, pero se puede juguetear con ella.

AMP tiene poca magia, y es negra.

Ya me olia mal al principio.

Cuando estuve estudiando el sistema AMP ya me pareció una patraña con oscuras motivaciones de Google. Todo lo que ofrecia se podia conseguir sin AMP. Recientemente he tenido ocasión de trabajar con el y es peor de lo  que creia.

Google te impone una serie de normas estrictas (no mas de 50kb de CSS, solo su propio javascript, su propio código html, etc.) que has de seguir para conseguir a cambio servirte de la “cache” de Google para acelerar tus paginas.
El problema es que te pide mucho y te da muy poco y con malas artes.

AMP te limita “por tu propio bien”

Para empezar, si google tuviera que hacer un parque seguro para niños bajo los parámetros de AMP lo que haría seria quitar los columpios. Te prohibe directamente usar técnicas que podrían ralentizar tu pagina, no se detiene a comprobar si lo hacen o no. Por ejemplo prohibe directamente usar JS, tienes que usar sus propios módulos para la interacción. Solo se pueden animar las propiedades transform y opacity en los CSS, ok, son las más rápidas, pero a veces necesitas animar otras propiedades y no tienen porque ralentizar nada pero no hay excepciones. Te limita el CSS a 50kbs, que es una cifra arbitraria que parece haber sido elegida por ser redonda…

Todo tiene muy poca magia, TODAS las técnicas que usa AMP para acelerar tu pagina pueden usarse sin pasar por el filtro de AMP, como se explica en este artículo con cuyas conclusiones estoy 200% de acuerdo:

To be fair to AMP naysayers….
Amp is fundamentally a system that just enforces certain page speed rules that can for the most part be achieved without using AMP.
AMP pages add complexity and must be learned. Some say it is better just to learn the right way to do things and just… do things right.

Además, es incompatible con otros sistemas que tambien “son el futuro” como Angular…

Aplicando AMP en la práctica.

El caso es que en mi trabajo he tenido que hacer unos portales AMP.
Bien, si no puedo usar JQuery, ni siquiera JS plano y sencillo, espero que a cambio me den las herramientas suficientes para no necesitarlo. Pues no. La impresión es que el sistema (que ya tiene 3 años) está a medias.
Los elementos son escasos y están muy mal documentados. Esta lista me parece muy corta.
Con un compañero backend, no hemos sido capaces de poner en el html algo tan simple como la fecha actual en una pagina, encontramos un modulo para poner un “time-ago”, un “Pull Request” para incorporar un modulo de fecha actual que llevaba 7 u 8 meses en el limbo y nada de información al respecto.
Doy por hecho que se podrá conseguir, pero no debería habernos sido difícil y dos tios no conseguimos hacerlo en su momento.

Llegados a este punto, uno se pregunta ¿esto es realmente una patraña como parece o soy yo que en mi ignorancia de frontend developer patatero no sé apreciarlo? Pero una búsqueda saca de dudas, no soy el único, y por parecidas razones.

Con AMP tu web puede ir mas lenta

En mis pruebas, las versiones sin AMP de nuestros portales (bien optimizadas y realizadas) eran más rápidas que con él. Lo cual es bastante lógico porque las optimizaciones de AMP ya estaban implementadas por nuestra cuenta (un único CSS, sin librerías, JS concatenados y minificados, imágenes optimizadas, etc) pero no necesitábamos cargar los scripts de gestión de AMP ni procesar el contenido HTML via JS.
La promesa de acelerar tu pagina solo se cumple cuando el usuario accede desde una pagina de resultados de google, que carga instantaneamente. ¿como? yo creia que se aprovechaba algún tipo de cache de Google tipo CDN o algo así, que la mejora implicaba las visitas a toda la web pero no es así. ¿como lo hace en realidad?
Cargando en segundo plano las paginas que aparecen en los resultados. 
Algo que, si quisiera, podría hacer con cualquier pagina (al menos con los recursos css y js, hay mil formas de utilizar esto) y no lo hace.

Tenemos la situación paradójica de que Google dice priorizar las paginas con AMP por ser más rápidas para navegar en móvil pero en realidad van (pueden ir) más lentas que antes y solo ir rápidas desde la primera visita en sus paginas de resultados.

Con lo cual acabas tendiendo dos versiones, una AMP para agradar a google y que te saque en el carrusel y una “buena” sin limitaciones.

Vender tu alma (contenidos) al diablo (ejem, Google)

Sobre otra vertiente negativa  de AMP, el hecho de que los contenidos se sirvan desde los servidores de google con su propia URL, el funcionamiento oscuro de los carruseles de Top Stories, etc. se está escribiendo mucho también y es bastante mas chungo que los problemas técnicos en los que me he centrado.

En fin, si te interesa estar en el carrusel de google tendrás que pasar por el aro, hay gente que lo ha probado y abandonado, por un tema u otro, como el control de las estadísticas con un sistema propio y no el impuesto por Google.

A mi desde luego, no me gusta nada.

Metodologías CSS (4): DRY CSS

¿CSS seco? ¿como el Martini?

No, Dont Repeat Yourself, nacio en el 2012.

¿Y de que va?

De no repetirse, de no repetirse, de no repetirse.

Bueno, para no repetir código tengo sass, variables, extends…

DRY dice que preprocesar es caca. Que no es css de verdad. Que dependes de librerias externas. (todo esto es muy muy discutible) y que se puede conseguir solo con css quimicamente puro.

La filosofia es no repetir las propiedades en cada clase sino agrupar las propiedades en grupos y asignar las clases a esos grupos.

Esta metodología no sataniza los selectores de herencia como las anteriores, lo necesita por su forma de funcionar, ya que uno de sus principios es tocar el html lo menos posible.
No usa las clases para definir el diseño sino para referirse al contenido, es decir, no usa cosas como .left sino .header

¿Que eso de los grupos?

Los grupos son conjuntos de propiedades css que van juntas, y le asignas las clases que las necesiten
Ya agrupamos  cuando varias clases comparten las mismas propiedades, pues hacer DRY es coger este concepto y llevarlo al talibanismo.
Aquí no haces clases y asignas propiedades, sino que haces grupos de propiedades y asignas las clases.Si tienes 5 elementos que usan el fondo blanco, habitualmente defines las 5 clases/selectores y añades en cada una: background:#FFF. O bien añades una “utility class”, (una clase que sirve para una función especifica y “universal”, como .light_background{background:#FFF} )Hemos dicho que DRY no quiere tocar el html, así que la utility class descartada, lo que se hace siempre según este sistema es

#LIGHT_BACKGROUND,
 .clase1 ul,
 .clase2 h2,
 .clase3,
 .clase4 li p,
 .clase5 .top
{
 background:#FFF
 }
Ojo, el id es solo para nombrar el grupo de propiedades, es para forzar que salga el nombre el grupo al inspeccionar un elemento. DRY dice que si tienes una sola clase asignada a un conjunto de propiedades, probablemente estes haciendo algo mal
DRY propone primero hacer una lista de grupos (separados en colores, texto, formas, estructuras y módulos), y luego asignar las clases según pertenezcan a uno u otro.
Los grupos se nombran en mayusculas según la función que hacen (#TEXT_RED, #MARGIN_BIG, #FLOAT_LEFT) y las clases semánticamente según su contenido (.top, .user .featured)Primero hacer grupos de propiedades:

{background:white;
 font-size:20px}
{background: grey;
 padding:20px}
{font-family: impact}

Luego nombrar esos grupos logicamente y en mayusculas utilizando ids que no se usan en el html:

#WHITE_PANEL
{background:white;
 font-size:20px}
  #GREY_PADDED
{ background: grey;
padding:20px}
#HEADINGS
{font-family: impact}

y luego asignar las clases necesarias.

 #WHITE_PANEL,
.menu-toggle,.post-term a,.term-link a,.site-title-text,.taxonomy-list-title .term-name
{background:white;
 font-size:20px}
  #GREY_PADDED,
.screen-title,.cycled-feature h3,.text
{ background: grey;
padding:20px}
#HEADINGS ,
h3,big,.footer h2,.cycled-feature .entry
{font-family: impact}

Echadle un ojo a este css y lo vereis enseguida:
https://s3.amazonaws.com/static.globalvoices/css/gv-news.css?updated=20171001

Que es de esta web:
https://es.globalvoices.org/

Si veis el html vereis que eso de “tocar el html lo menos posible” tampoco se cumple mucho…

 ¿Y que ventajas tiene?

– Css mas cortos.
– Promueve buenas practicas de diseño  ya que tienes que pensar en patrones de diseño en vez de en elementos sueltos
– Solo usa css “puro”, sin preprocesadores
– Al ver todas las clases afectadas por una propiedad es más fácil ver las interdependencias y herencias, sabes a quien afectara una propiedad al cambiarla
– No necesita editar el html, puede servir para “estilar” sitios donde no tienes acceso (o es difícil) a la fuente html, como wordpress.
– Es compatible con otras metodologías como smacss , ya que solo se mete en como organizar clases y selectores

¿Y como se apaña con el responsive?

Tienes que duplicar los grupos en cada punto de ruptura con las nuevas propiedades.

¿Y tu que piensas?

Lo veo flojo.
Y que llevar tan al extremo el hecho de no repetir código arrastra inconvenientes en otros aspectos. Creo que es más sencillo y legible usar preprocesadores y gastar unos kbs más si hace falta. Si no ves problema en usar preprocesadores para no repetir código este sistema pierde muchos puntos…

Al final hay listas kilometricas de clases asignadas a una propiedad que a mi modo de ver traslada el problema de sitio más que solucionarlo.

Tambien es verdad que se hace muy raro porque obliga a pensar al revés, desde la propiedad > clase > grupo en vez de elemento > clase > propiedad como estamos habituados por la filosofía de css.

A pesar de todo creo que tiene cosas interesantes y hay que tenerla en cuenta si no para seguirla al 100, quizá para aplicar algunos conceptos como los grupos definidos de propiedades.

Una presentación sobre el sistema donde se ven sus principios y forma de funcionar:

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”?

No, BEM dice que no.
Dice que anidar selectores  es malo, porque es impredecible, añade especificidad, causa muchos problemas y mejor no usarlo. Impide reutilizar bloques de una parte a otra, y gran parte del trabajo de css es resetear y sobrescribir valores heredados. Además complica el trabajo cuando varios developers trabajan sobre el mismo proyecto.
BEM propone eliminar la anidacion de los selectores 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 jerarquia de selectores natural de css a una jerarquia 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?

Depende, soy un clasico, 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.

Pero claro, a uno se le revuelven las tripas cuando le proponen renunciar a la jerarquia de selecotres 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 jerarquia “de maquetacion” 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 pseudoDOM 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 jerarquia 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 y comodo aprovechar la jerarquia en un proyecto mas pequeño o liderado por una sola persona.

Y también puedo imaginar un mundo alternativo  horrible donde la jerarquia 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.

El maravilloso em como unidad de medida (y parte 2)

Lo bueno del em es que podemos usarlo como unidad de medida casi en cualquier propiedad css. Pongamos que tenemos la típica lista de thumbs que van a  contener miniaturas de diversas fotos de las que no conocemos sus dimensiones. Lo más fácil seria seria darles a todas las imágenes un ancho del 100%,  damos un ancho del <li> en porcentaje y dejar que el alto del <li> se ajustara solo al escalarse la imagen, pero como cada imagen tendrá una relación ancho/alto distinta, nos formara escalones que descuadran la retícula. ¿como podemos poner un alto “fijo” relativo al ancho?

(El tema de encajar la imagen lo resolveríamos poniéndola como position:absolute ( y overflow hidden al <li>), o como a mi me gusta, usandola de background del <li>y tirando de background-size:cover)

No podemos usar altos en porcentaje, porque son muy problemáticos, y exigen que esté definidos todos los altos de todos los padres donde se localice hasta llegar en la jerarquia del DOM a HTML. Los anchos en porcentaje funcionan, los altos no.

Podríamos usar el ancho de ventana (vw) como referencia (li{ height:20vw}, por ejemplo), con limitadores media query por arriba y por abajo, pero vw exige ser limitada cada vez que se utilice para evitar los problemas que comentaba en la primera parte. 

Podriamos usar una imagen “dumb”, un gif transparente vacio con las proporciones que queramos, pero es una solucion un poco sucia, y con ello solo podemos escalar el alto del <li> (o <div> o lo que sea) que la contenga.

Recordemos que em es una referencia (ojo, acumulable y relativa, como comento al final del articulo anterior) al tamaño del texto definido en el <body>, y como lo hemos definido tal que así:

body {
 font-size: 3.2vw;
 line-height:1.2;
 }

@media (max-width: 360px) {
 body {font-size:10px}
 }

@media (min-width: 800px){
 body {font-size25px}
 }

Estamos definiendo que em valga:
• 10px hasta 360px de ancho de ventana.
• El 0.032% del ancho de ventana hasta 800px de ancho de ventana (con una ventana de 480px, em valdria 15.36px).
• 25px en adelante.

Inciso: No necesariamente el tamaño que definamos en el body tiene que usarse para los textos, yo habitualmente uso una definición de <p> independiente del tamaño de fuente definido en el body y uso este ultimo lo utilizo para los titulares y las dimensiones gráficas (margenes, relaciones alto/ancho, etc). Y me facilita mucho las cosas poder tener una referencia única que usar en el máximo numero de situaciones posible.

Volvamos al principio, recordemos que esto era para solucionar el alto de los <li>, una vez definido lo anterior, podemos  ajustar el alto de los<li>s asi:

li{ width: 20em; height: 1.5em}

Y tendremos una web que escala los contenidos correctamente sin más complicación.

Lo suyo seria poner el media query limitador “por arriba” en la misma medida que el max-width del contenedor padre que tenga la web o del <ul> que tenga los thumbs.

Esta forma de trabajar no es la panacea, y tiene sus propios inconvenientes, pero es otra herramienta más que tenemos a nuestra disposición para resolver problemas que nos puedan surgir.

Y en fin, solo recordar que con CSS siempre hay mil formas de hacer las cosas y elegir una u otra solo depende del caso concreto, del target de la web o al final, del gusto personal.

Tengo pendiente preparar un codepen o algo por estilo para que todo esto se vea mucho mas claro hasta entonces, podéis consultar cualquier duda en los comentarios, que para eso están ;).

El maravilloso “em” como unidad de medida (parte 1)

Antes usaba pixels como unidad de medida para las fuentes. Llegó el responsive y hacia como muchos, usaba saltos media query para ir cambiando el tamaño conforme lo hacia el tamaño de pantalla… (perdón, mejor “ventana” en vez de pantalla porque habitualmente no podemos disponer de todo el tamaño de pantalla por las áreas de interfaz y otras cuestiones)

Esto tenia varios problemas, uno de ellos la inconsistencia entre el tamaño de la ventana y la fuente. En determinados tamaños de pantalla (y ahora hay cientos) un titular se salia del marco, o aparecia un salto de linea que desmaquetaba la pagina y afeaba el conjunto.

Descubrí “vw” (ViewportWidth) como unidad de medida. Perfecto, con h1{ font-size:2vw} Hacias que el tamaño de la fuente fuera el 2% del ancho de pantalla. Ahora si, escalabas la ventana y la fuente escalaba en la misma proporción, se acabaron los saltos de linea ocultos. Los textos se ampliaban como si fuera fotosop.

Problema: Al estar ligados al tamaño de la ventana cuando la pagina habia terminado de escalar (el tipico .container{max-width:…) el texto seguia aumentando. Además, a partir de determinado tamaño, la fuente adquiria proporciones horribles.

Solución : Limitar con media querys tanto el mínimo como el máximo del tamaño. Por debajo de 479 el mínimo legible, por arriba del ancho total de la página el máximo estético o funcional. Pero surge un nuevo…

Problema: Es un coñazo tener que añadir media querys a todos y cada uno de los tamaños de texto, h1, h2, h3, p, etc.

Solución: Aquí acude en nuestra ayuda el viejo “em”. El em es una referencia relativa al tamaño de fuente heredado. Toma como valor el inmediatamente definido  anterior. De esta forma, si definimos en el body un font size de 14px y al h1 le aplicamos un 2em, h1 valdrá 28px. Si metemos el h1 en un div que tenga como font size 1.5em, el h1 tendrá 42px de tamaño (14px * 1.5 * 2). Si el div tiene un tamaño en pixels, el em se calculara en base a ese tamaño, no el del body.

Ya tenemos todas las herramientas que necesitamos.

Aplicamos al body un font-size basado en vw limitado por arriba y por abajo con media querys. Pongamos 1.7em, 12px por debajo de 479px y 18px por encima de 1024px. Si calculamos el tamaño en el momento de corte del media query (1024/100*1.7= 18px aprox.) el cambio de em’s a pixels sera continuo y quedara mas fino.

El resto de fuentes las definimos con sus proporciones en em’s y solo nos ha hecho falta dos media querys para definir los tamaños de todas las fuentes de la web, y se escalaran de forma continua con el ancho de la ventana. Además todos los tamaños de fuente estarán referenciados a un único valor, el del body,esto hace muy fácil aumentar o disminuir todas las fuentes a petición del usuario, según dispositivo, etc.

Esto de tener un valor relativo a un ancho limitado de pantalla nos da juego para más cosas que contare en el próximo capítulo.Hay que tener siempre en cuenta el efecto acumulativo de los em’s. Todos los textos que metamos en un div con font-size:0.5em tendrán la mitad de tamaño. Podemos usar la variante “rem”, está un pelin menos soportada, y hace referencia “directa” al tamaño definido en el body (RootEm) independientemente de los tamaños intermedios.

Esto de tener un valor relativo a un ancho limitado de pantalla nos da juego para más cosas que contare en un próximo articulo.