miércoles, 17 de enero de 2018

Example how to slice a image into a tiles with aws lambda and upload them to S3 with nodejs


This is a example code that I made to test the concept. The function was triggered by a "Put on a bucket"  that means when a image is uploaded to the bucket on S3.

I hope this will help others solve problems



viernes, 3 de noviembre de 2017

Docker Postgre persist data with volume: Error could not link file pg_xlog on windows 10 with toolbox


This is a problem that could happen if you try to mount a volume in this way:

https://stackoverflow.com/questions/45632593/postgres-docker-container-data-fails-to-mount-to-local

I solved this problem creating a volume :

docker volume créate  --name  paneek

and later only using it on my docker-compose.yml:

version: '2'
services:
 
  app:
    build:
      context: ./
      dockerfile: app.dockerfile
    working_dir: /var/www
    volumes:
      - ./:/var/www
    links:
      - pgsql   
 
  web:
    build:
      context: ./
      dockerfile: web.dockerfile
    working_dir: /var/www
    volumes_from:
      - app
    ports:
      - 80:80
    links:
      - app

  pgsql:
    image: "postgres:9.5"
    #to be available to use pgadmin
    ports:
      - 5432:5432
    environment:
      POSTGRES_USER: postgres
      POSTGRES_DB: postgres
      POSTGRES_PASSWORD: local
    volumes:
      - paneek:/var/lib/postgresql/data     
volumes:
  paneek:


Note: On Windows with toolbox there is not another way to do it.









jueves, 26 de octubre de 2017

Redirect http to https on PHP with Heroku using .htaccess


There is one thing that you need to understand with SSL and Heroku. The SSL connection is actually terminated before the request reaches your app, it is done heroku routing layer and all requests are sent to your app using plain HTTP.

To know if a request was made using HTTPS you need to check the X-Forwarded-Proto HTTP header for its value. "https" means it used SSL, "http" means it didn't. You should then perform the URL rewrite based on this. This is an example of how you can do this using the .htaccess file.

##Force SSL

#Normal way (in case you need to deploy to NON-heroku)
RewriteCond %{HTTPS} !=on

#Heroku way
RewriteCond %{HTTP:X-Forwarded-Proto} !https

#If neither above conditions are met, redirect to https
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]


The secret sauce is the line with HTTP:X-Forwarded-Proto.


links:
https://devcenter.heroku.com/articles/http-routing
https://stackoverflow.com/questions/26489519/how-to-redirect-to-https-with-htaccess-on-heroku-cedar-stack

jueves, 6 de julio de 2017

Javascript reduce function


var users = [{
id: 1,
name: 'saul',
age: 2,
pets: ['cat','dog']
},
{
id: 1,
name: 'andrie',
age: 6,
pets: ['cat']
},
{
id: 1,
name: 'manuel',
age: 6,
pets: []
}];

users.reduce((accumulator, currentElement, index, array) => {
return accumulator.concat(currentElement.pets);
}, []);

//result
["cat", "dog", "cat"]


Reduce toma una callback y un valor initial opcional que es el acumulador que es pasado a la callback en cada iteracion. Entonces Reduce empieza a iterear por cada elemento llamando a la callback pasando el acumulador y el element sobre el cual se esta iterando.

La primera vez acumulador es un arreglo vacio por que es el valor inicial, las siguientes veces acumulador tiene el valor retornado por  la previa interacion. Asi es como al final de la iteracion reduce devuelve el valor de "accumulator".

Aqui un ejemplo usando objectos

var myArr = [
{ rating: 5 },
{ price: 200 },
{ distance: 10 }
];

var myObj = myArr.reduce(function( memo, item ) {
memo = Object.assign(memo, item);
return memo
}, {} );

//result
{rating: 5, price: 200, distance: 10}


Espero haber despejado dudas
















lunes, 2 de enero de 2017

Entendiendo Shadow DOM V1 y custom elements V1

Shadow DOM es uno de los 4 estandares de Componentes web
 Con Shadow DOM puedes crear nuevos elementos HTML y CSS, con su propio scope. Y puede ser combinado con "Custom elements" haciendo un unico elemento con sus propio html, css, js.

DOM Aislado: Todo el html esta aislado del html principal, intentar esto: document.querySelector() , no va a devolver nada.

CSS aislado: Todo el CSS dentro del elemento no afectara al html principal. Puedes usar id, clases con el mismo nombre y no tendras problemas.

Con esto tenemos un panorama de que podemos construir nuestras aplicaciones web en pequeños pedazos y unirlos a como queramos.

Por el momento Web components no es del todo estandar en los navegadores, pero por suerte podemos usar un polyfills.

http://webcomponents.org/polyfills/


Ejemplos de como usar Shadow DOM, por ahora solo funciona en chrome (Solo tienes que examinar el codigo para ver como funciona.):
https://saulburgos.github.io/practices/2017/shadowdom/
https://saulburgos.github.io/practices/2017/customelements/

Como Shadow y custom elements no son totalemente estandar por el momento, no puedes usarlos cuando quieras, a menos que uses https://www.polymer-project.org , que es una library con todos los polyfills necesarios para que funcione en todos los navegadores

Confusion

"Web components" es el termino que encapsula 4 tipos de API hasta el momente: html templates, shadow dom, html import y custom elements.  Pero en internet mucha gente se refiere a "web components" al uso mezclado de estas APIs. Por ejemplo : shadow dom y custom elements.

Asi que no te confundas si en un tutorial ves este tipo de uso.


links:
https://developer.mozilla.org/en-US/docs/Web/Web_Components/Custom_Elements
https://developers.google.com/web/fundamentals/getting-started/primers/customelements 
https://www.smashingmagazine.com/2016/12/styling-web-components-using-a-shared-style-sheet/
https://hayato.io/2016/shadowdomv1/
https://developer.mozilla.org/en/docs/Web/HTML/Element/template
https://www.smashingmagazine.com/2014/03/introduction-to-custom-elements/

sábado, 31 de diciembre de 2016

Entendiendo la Web notification API

La Web notification API nos permite mandar notificaciones a los usuario a como lo hacen las app nativas.

Para usar primero necesitamos que el usuario de permiso con el siguiente codigo:


Notification.requestPermission(function(status) {  // status is "granted", if accepted by user
    var notificationMsg = new Notification('Title', { 
       body: 'I am the body text!'
    }); 
});

Puesdes ver la demo en este link:  https://saulburgos.github.io/practices/2017/webnotification/

 Una vez con el permiso, usamos el objecto Notificacion para crear un instancia del mensaje que queremos usar. Mas adelante si necesitamos verificar este permiso de nuevo podemos consulta la propiedad "permission", que puede tener los valores de : "default, granted, denied"

Notification.permission

Esta API comunmente se usa en conjunto con los services worker y push API, para notificar de la manera en como lo hacen las app nativas cuando no tienes la app abierta

links
https://developer.mozilla.org/en-US/docs/Web/API/Notifications_API/Using_the_Notifications_API
https://developer.mozilla.org/en/docs/Web/API/notification

viernes, 30 de diciembre de 2016

¿ Como saber con javascript si estas online ó offline ?

El objeto "navigation" puede ayudarnos con esto:

https://developer.mozilla.org/en-US/docs/Web/API/NavigatorOnLine/onLine

 Solo tenemos que consultar esta propiedad que nos devolvera un valor true/false.

window.navigator.onLine;

Su uso es:

if (navigator.onLine) {
  console.log('online');
} else {
  console.log('offline');
}
 

Tambien podemos escuchar un eventos para saber cuando hay conexión :

window.addEventListener("offline", function(e) { 
  console.log("offline");
});

window.addEventListener("online", function(e) { 
  console.log("online"); 
});

links

https://developer.mozilla.org/en-US/docs/Web/API/NavigatorOnLine/onLine



jueves, 29 de diciembre de 2016

Entendiendo la Cache API


Comunmente esta API es usada en conjunto con la API Service worker, pero puedes usarlo independientemente aunque no he encontrado un ejemplo de su uso fuera de esta API. Segun la definicion se usa para guardar objectos "Request" y "Response", esto significa que puedes dar las peticiones que haces al server y tambien las respuestas del server.

Una parte importante a saber que casi todos los metodos de esta API usan promesas. Para crear un espacio donde cachear todos nuestros assets solo necesitamos llamar este metodo del objecto "caches"

caches.open('test-cache').then(function(cache) {
  // Cache is created and accessible
});

El nombre 'test-cache' es una namespace o identificador de la cache que hemos creado. De esta manera podemos usarla luego.

Para agregar elementos a la cache creada se usa comunmente los metodos "Add" y "addAll".

cache.add('/sw-test/index.html').then(function() {
  //request have been added to the cache
});

cache.addAll(['/', '/images/logo.png']).then(function() {
  //requests have been added to the cache
});

La diferencia es que en la segunda se pasa un arreglo de urls. Algo que destacar aqui es que usar el metodo "add" es lo mismo que usar fetch de formal normal con put de esta manera:

fetch(url).then(function (response) {
  if (!response.ok) {
    throw new TypeError('bad response status');
  }
  return cache.put(url, response);
});

O peticiones personalizadas con el object "Request" de esta forma:

cache.add(new Request('/page/1', { /* request options */ }));
 
"add" and "addAll" son como atajos del metodo "put" por que con este metodo pones en cache usando key/value de esta manera:

fetch(url).then(function (response) {
  return cache.put(url, response);
});

Revisar la cache

 Para revisar que hemos puesto en la cache primero necesitamos abrirla y despues explorar los elementos usando el metodo "keys"de esta manera:

caches.open('test-cache').then(function(cache) { 
 
  cache.keys().then(function(cachedRequests) { 
    // [] Array of all of caches keys
  });
});

Para buscar dentro se usan los metodos "match", "matchAll":

caches.open('test-cache').then(function(cache) {
  cache.match('/page/1').then(function(matchedResponse) {
    console.log(matchedResponse);
  });
});

En el ejemplo anterior, estamos buscando el objecto en cache que correspondo con la peticion a 'page/1'

Otros usos comunes serian leer y buscar:

caches.open('test-cache').then(function(cache) {
  cache.delete('/page/1');
});

caches.keys().then(function(cacheKeys) { 
  console.log(cacheKeys); // Get all the namespace created
});

caches.delete('test-cache').then(function() { 
  console.log('Cache successfully deleted!');  
});

Dentro de un service worker, el proceso seria algo asi:

  • El service worker intercepta todas las peticiones al server, ya sean ajax o cargar otras paginas web.
  • Una vez interceptada la peticion, revisamos en nuestra cache si esa peticion ya esta en la cache
  • Si es asi devolvemos el objecto en cache.
  • Si no dejamos que la peticion siga su curso, al terminar la metemos al cache.

Ejemplo de esto:

//trigger on url changes and requests to the server
serviceWorker.addEventListener('fetch', function(event) { 
 //search in the cache for the request that is in progress
 var cacheFound = caches.match(event.request).then(function(response) {
  
  if (response) {
   //return the object cached
    return response;
  } else {
   //if not, we make the normal request
   return fetch(event.request); 
  }  
 });

 //we pass the promise 
 event.respondWith(cacheFound);

});

Aqui he hecho un ejemplo del uso de la cache API sin un service worker

Links

https://developer.mozilla.org/en-US/docs/Web/API/Cache
https://davidwalsh.name/cache



Entendiendo la Promise API

Las promesas son ahora la manera preferida de trabajar y en el futuro sera muy pocos los casos en los que necesitaras una callback. jQuery tiene su propio sistema de promesas.

Pero ahora tenemos una API promise nativa que podemos usar. Su uso es muy sencillo:

var promise = new Promise(function(resolveFn, rejectFn) { 
 
 //you can do here operations and later decided if resolve or reject the promise
 //using the objects
 setTimeout(function() { 
  resolveFn(10);

 }, 3000);

});

//when is resolve
promise.then(function(result) {
 console.log(result);
});

//when is rejected
promise.catch(function(result) {
 console.log(result);
});

Despues de haber instanciado el objecto "Promise" tienes los metodos "resolveFn" y "rejectFn" los cuales puedes ejecutar cuando tu quieras en un futuro, los cuales van a ejecutar los metodos pasados a "then" y "catch".

Un interesante metodo de "Promise" es "all", el cual recibe un arreglo de promesas y ejecuta "then" cuando todas han sido "resolve".

Promise.all([promise1, promise2]).then(function(results) {
 // Both promises resolved
})
.catch(function(error) {
 // One or more promises was rejected
});

Link

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise
https://davidwalsh.name/promises



Entendiendo la Fetch API

Ahora ya no usamos Ajax para hacer peticiones al server ahora usamos Fetch. Por que ? por que nos permite usar promesas en lugar de callbacks, permitiendo un codigo mas limpio.

Una peticion con fetch basica es de la siguiente manera:

fetch('./api/some.json').then(function(respond){
    //exito
}).catch(function(err) { 
    //Error en la peticion
});

La promesa se mira en accion con los metodos "then" y "catch", a los cuales se le pasa metodos para ser ejecutados cuando terminen.

Then : Es ejecutado cuando la peticion termina correctamente.
catch: Es ejecutado cuando en la peticion ocurrio un error.

Fetch retorna un objecto stream cuando la peticion es exitosa, el cual tiene muchos metodos para usar. Puedes consultarlos aqui. El ejemplo completo seria asi:

fetch('./api/some.json').then(function(response) { 
   
    if (response.status !== 200) { 
      console.log('Looks like there was a problem. Status Code: ' + 
        response.status); 
      return; 
    }

    // Examine the text in the response 
    response.json().then(function(data) { 
      console.log(data); 
    }); 

}).catch(function(err) { 
  console.log('Fetch Error :-S', err); 
});

Otras propiedades interesantes del objecto response son:

fetch('users.json').then(function(response) {  
    console.log(response.headers.get('Content-Type'));  
    console.log(response.headers.get('Date'));

    console.log(response.status);  
    console.log(response.statusText);  
    console.log(response.type);  
    console.log(response.url);  
});

El objecto response puede ser de varios tipos para una mejor descripcion visita este link.


Adicionalmente puedes usar los objectos "Request" y "Header" para personalizar los peticiones fetch. Tomando un ejemplo de david walsh, seria asi:

// Create an empty Headers instance
var headers = new Headers();

// Add a few headers
headers.append('Content-Type', 'text/plain');
headers.append('X-My-Custom-Header', 'CustomValue');

// Check, get, and set header values
headers.has('Content-Type'); // true
headers.get('Content-Type'); // "text/plain"
headers.set('Content-Type', 'application/json');

// Delete a header
headers.delete('X-My-Custom-Header');

// Add initial values
var headers = new Headers({
  'Content-Type': 'text/plain',
  'X-My-Custom-Header': 'CustomValue'
});

var request = new Request('https://davidwalsh.name/some-url', {
  headers: new Headers({
    'Content-Type': 'text/plain'
  })
});

fetch(request).then(function() { /* handle response */ });

Es una manera facil y alternativa del uso de ajax.

Links:

https://davidwalsh.name/fetch
https://developers.google.com/web/updates/2015/03/introduction-to-fetch
https://developer.mozilla.org/en/docs/Web/API/Fetch_API
https://hacks.mozilla.org/2015/03/this-api-is-so-fetching/ 



miércoles, 16 de noviembre de 2016

Libro Google maps Javascript - Capítulo 6 : Hacer un preview de Google streetview desde un input file


Volver al indice




Hace pocos dias tuve la necesidad de crear una previsualización de un panorama google streetview usando un input file, esto fue para el proyecto de Tours virtuales . Por que muchos usuarios estaban subiendo imagenes incorrectas y hasta que eran procesadas podian ver los resultados finales. Esta era tediso asi que , he creado una funcionalidad de previsualización.

 En el siguiente link puedes ver el resultado:

https://jsfiddle.net/SaulBurgos/rg5o213b/3/

Los pasos son los siguientes:
  1.  En el input file definimos un metodo que sera llamado "createPreview" cuando el input cambie
  2. "createPreview" usan la API FileReader para leer el archivo
  3. Creamos la instancia de FileReader y definimos 2 metodos para escuchar los eventos: "onload" y "onprogress"
  4. onload se dispara cuando FileReader lee completamente el archivo, pero la imagen aun no ha sido cargada
  5. Para cargar la imagen creamos una imagen con la Image  API, al igual que con FileReader podemos definier un metodo para correrlo cuando la imagen ha sido cargada con "onload"
  6. Despues solo usamos canvas para crear un objecto donde poner esta imagen. Esta parte es la mas importante por que aqui se redimensiona la imagen a 1024x512. De esta manera evitamos que el navegador se congele, por si el usuario ingresa resolusiones muy grandes.
  7. El metedo encargado de la redimension es "drawImage" , despues con el metodo "toDataURL" obtenemos la nueva imagen redimensionada y la pasamos a Google streetview




http://www.paneek.net/





lunes, 12 de septiembre de 2016

Como sincronizar el scroll de 2 divs con hijos de tamaños diferentes en Javascript


Para que este post pueda ser encontrado en ingles pondre esta linea:

How do I synchronize the scroll position of two divs  with different height ?

Hoy en el trabajo nos sentamos un buen amigo mio y yo e hicimos este pequeño  demo de como funciona. La verdad que todo el credito se lo lleva mi amigo Hod es su algoritmo . Yo solo ayude con la parte de Javascript y unas pocas cosas

Espero que a alguien le sea util.





jueves, 25 de agosto de 2016

Libro Google maps Javascript - Capítulo 6 : Descargar imagenes de Google maps streetview


Volver al indice



Si estas buscando como descargar las imagenes de  Google streetview  la unica forma de hacerlo es atraves de su API

 Es facil de usar solo tienes que pasar estos parametros:

https://maps.googleapis.com/maps/api/streetview?size=600x300&location=46.414382,10.013988&heading=151.78&pitch=-0.76

Si copias y pegas ese link en tu navegar podras ver la imagen.  Ten en cuanta que si quieres usar la version gratis solo puedes descargar imagenes de 600x300 , si las quieres en HD y mas grande tienes que pasar por caja aqui la descripcion de precio de google

https://developers.google.com/maps/documentation/streetview/usage-limits

He creado un ejemplo donde puedes probar la API, Solo mueve el visor donde tu quieras y has click en el boton "get image".

http://jsfiddle.net/SaulBurgos/g3r8Lkws/2/




http://www.paneek.net/





viernes, 19 de agosto de 2016

Javascript : testeando Page Visibility API

Un ejemplo practico de uso de Page Visibility API , es para saber si el usuario cambia de tab en el misma ventana del navegador, pero no funciona si el usuario se pasa a otra ventana. El soporte para esta api es muy decente : http://caniuse.com/#feat=pagevisibility

Posibles usos
  • Pausar video o sonidos
  • Detener animaciones que nadie esta viendo
  • Detener llamadas al servidor si nadie las vera

Ahora un ejemplo

Visita este link y veras como el video es detenido cuando cambias de tab. 

Link:






lunes, 15 de agosto de 2016

Si programas tienes que usar una guia de estilos para tu codigo...

Si actualmente estas programando y no estas usando una guía de estilo para tu código de acuerdo al lenguaje que usas,  estas cometiendo un gran error...

Una guía de estilo de código en palabras simples es como tu código luce , como lo ven los demás. Si miras todo el código que has escrito hasta ahora podrás notar un cierto patrón, ese es tu propio estilo.
El problema con esto es que no es entandar y la mayoría de las veces solo tu podrás entenderlo.

No serial genial que todos escribieran el código como tu lo haces ?  .... Por esa razón mi buen amigo es que existen las guía de estilo de código, para que todos podamos leer y entender el código de los demás.

Una guía de estilo de código por lo general tiene lo siguiente:

  • Como y cuando usar comentarios
  • Como usar y cuanto espacio e indentación deberías de utilizar
  • Nombres adecuados para tus variables y funciones
  • Como agrupar tu código
  • Que técnicas usar o cuales no, dependiendo del lenguaje
Si tu objetivo es trabajar en una gran empresa, necesitas aprender los estilos de código para cada lenguaje que usas. Es un gran dolor de cabeza cuando un nuevo programador quiere escribir código a como le da la gana, Si tu eres uno de estos seguramente no vas a durar mucho.

Una rápida búsqueda en Google puede ayudarte a encontrar los estilos que buscas, pero a continuación podre algunos





sábado, 23 de julio de 2016

Mejora tu codigo CSS, no hagas desastres !!

En este post voy a repasar algunas técnicas, ideas y metodologías que uso para escribir un código CSS escalable, mantenible, predecible y reusable. 

El 99% de los programadores está de acuerdo: “Nombrar cosas es por mucho lo más difícil de hacer cuando programas”. Buscar los nombres correctos para variables, métodos ó los nombres de clases para elementos HTML es muy complicado, esto es debido por que no podemos predecir el futuro de los diseños y funcionalidades. Por ejemplo:

El nombre de una clase de un elemento HTML puede tener mucho sentido hoy, pero si el diseño cambia una semana después, ese nombre de clase puede no encajar en la nueva estructura. También pasa lo mismo cuando una característica es añadida ó removida en una aplicación debido a que el cliente así lo decidió. Como resultado de estos cambios tenemos que hacer un refactoring de nuestro código para que ahora pueda tener sentido. Este ciclo se repite constantemente a lo largo de cualquier proyecto, por lo cual tenemos que tener mucho cuidado cuando nombramos los elementos.

No existe una técnica única para nombrar elementos correctamente, pero existen ciertas guías que pueden ayudarnos. En este artículo quiero enfocarme en cómo nombrar los elementos en CSS.

En el momento en el que estemos bloqueados y no sabemos que nombre de clase ponerle a un elemento HTML, usa las siguientes sugerencias, las cuales podemos dividir en:

Nombres de clases funcionales


Ejemplos de estos nombres: save_button , delete_button , selected_tab. El nombre de estos elementos está basado en la función que desempeñan. Con solo leer el nombre sabemos que ese boton es por ejemplo para guardar.

El diseño puede cambiar pero la función de ese elemento no lo hará. Nombrar elementos de esta manera seria lo ideal pero no a todos los elementos podemos darles nombres basados en su funcion. Por ejemplo una caja de texto necesita una sombra para verse bien ó un icono tiene que ser azul por que se mira bonito.

No todo estilo visual en un sitio web tiene una justificación funcional para poder nombrarlo.


Nombres de clases basado en el contenido


Ejemplo de estos nombres: intro_text , description_item , image_product. Este tipo de nombres describen el contenido de los elementos. Esta es la manera más obvia y facil de nombrar elementos. En sitios web pequeños es lo mejor que puedes hacer, pero para grandes proyectos no es lo ideal escribir todo tu estilo usando una única clase.


Nombres de clases basado en la presentación


Ejemplos de estos nombres: red_button , big_text , vertical_menu, horizontal_menu , bold_text . Este tipo de nombres describe el estilo del elemento, es decir la manera en como lucen y son presentados en el sitio web. También este tipo de nombres son muy descriptivos para cualquier programador, por ejemplo: “border_image” con solo leer ese nombre sabes que el estilo seria unos bordes en la imagen.

La ventaja de estos nombres es que son reutilizables, por ejemplo “big_text” puede ser usado en muchos elementos donde queremos el texto en grande, no importa si es un título de página, nombre de persona ó título de producto, solamente nos interesa que sea un grande.

Piensa en esto : Los nombres de clases tienen significado y propósito, evita nombres que no sean descriptivos. Mantén en mente que los nombres de clases son para programadores, no para usuarios., Piensa en que un nombre de clase con solo leerla tiene que entregar toda la información posible sobre lo que hace a los programadores y a tu futuro yo.

Siempre debemos procurar que nuestro código CSS sea:

Predecible: Tus reglas CSS deben comportarse como su nombre lo indica. Cuando cambias ó actualizas un estilo solo debe afectar la parte que estas trabajando, no debería de afectar otra partes adicionales Ejemplo: vertical_menu , big_button, text_center .

En estos ejemplos se puede ver claramente la intención del estilo.

Reusable: Tus estilos deberían de ser lo suficientemente abstractos y estar lo menos atados posibles a un elemento en específico, para permitirte construir nuevos estilos a partir de ellos, sin tener que reescribir el mismo estilo de nuevo. Ejemplo: shadow_big , round_square.

Estas dos clases se puede usar en un mismo elemento para darle sombras y crear bordes redondeados y así crear un nuevo estilo combinado.

Mantenible: Cuando el diseño web cambia y hay nuevos elementos en escena, tu código CSS no debería de sufrir un cambio drástico, un nuevo elemento Y no debería de afectar al elemento X antiguo.

Ejemplo: Si tienes un sidebar a la izquierda y el nuevo diseño dice que ahora son 2 sidebar al mismo tiempo en ambos lados. Con solo crear una clase nueva llamada “sidebar_rigth” deberías de solucionar el problema

<div class=”sidebar sidebar_left”>menu</div>
<div class=”sidebar sidebar_rigth”>menu</div>

De esta manera la clase “sidebar” aplica el estilo general y las otras solo cambian la posición.

Escalable: Esto significa que tu código CSS debe de ser fácilmente editable por una persona o por un equipo, que no tiene una curva de aprendizaje alta  y es facilisimo de entender. Solo por que tu eres el único programador hoy actualizando este código no quiere decir que siempre sera así


Malas practicas en CSS


Ahora vamos a ver un poco de malas practicas CSS para saber que no debemos de hacer.
Dar estilo basado en el padre:  Ejemplo:

#produc title_shadow {
}
#menu item_visited {
}
.contact .image_responsive {
}

En los 3 ejemplos anteriores no podremos reusar los estilos de “title_shadow” para texto con sombras, “item_visited” para links visitados y “image_responsive” para imagenes responsivas por que estamos forzando a que sean hijos de otros elementos.

Cuando tengas estilos generales, siempre analiza si puedes reusarlos en otros elementos de tu web.

Selectores CSS muy complicados:  Es cierto que CSS nos brinda muchos selectores que podemos usar, pero ojo no por eso vamos a abusar de ellos. Los siguientes son algunos malos ejemplos:

#menu ul li {
}
#sidebar > div + p {
}
table tr ul p {
}

Entre más selectores uses más amarrado esta al HTML, lo que provoca que cualquier cambio en el diseño web afecte a tu CSS también. Este tipo de reglas no son reusables, ni mantenibles por que están apuntando a un elemento en una posicion específica en el HTML

¿ Como podria otro elemento usar el mismo estilo, si tiene una estructura HTML distinta ?

Simple no puede. En lugar puedes usar nombres de clases directos. Los ejemplos anteriores podrían reescribirse así:

.menu_item {
}
.paragraph_description {
}
.descrition_table {
}

Nombres de clases simples y sin significado: 

.title {
}
.content {
}
.name {
}

Este tipo de nombres hay que evitarlos, son muy genéricos y no son informativos para el programador, por ejemplo ”title” ¿ titulo de que ?. con solo leerlo no podemos saber si es en un menú, en una sidebar ó titulo de artículo.

Otro problema es que como el nombre es muy generico, algun compañero podria sobreescribir tu CSS con mucha facilidad por accidente. Este tipo de nombres producen CSS impredecible.

Un estilo que hace mucho:

.user_messages {
     position: relative;
     border: 1px solid gray;
     background-color: white;
     font-size: 15px;
     marging-top: 50px;
     left: 10px; 
}

Imagina que el estilo anterior es para para un caja que muestra los mensajes de usuarios, arriba en el centro de la página. Tiene un margen y lo mueve un poco a la derecha.

¿ Que pasa si quiero mostrar esta misma caja al mismo tiempo en una sidebar derecha ? 

Luciria muy mal , porque el estilo está haciendo muchas cosas: Esta definiendo aspecto y posicion dentro de la misma regla. El aspecto es algo que podemos reusar pero la posicion no, por eso toda la regla está comprometida. Lo mejor sería dividirla así:

.user_messages {
     position: relative;
     border: 1px solid gray;
     background-color: white;
     font-size: 15px;
}
.user_message_top {
    marging-top: 50px;
    left: 10px; 
}

Así el elemento en la sidebar solo puede usar la clase “user_messages” para obtener el estilo.


Usar clases solo para dar estilos y solo eso


El problema aquí es que en proyectos grandes te encuentras con nombres de clases que tienen muchos propósitos por ejemplo: para dar estilos , para hacer alguna función por medio de javascript , como ancla para algún plugin jquery , etc.

Las clases tienen muchas responsabilidades y cuando lees los nombres no son muy descriptivos, no hay nada que te indique para que son. Removerlas ó actualizarlas es todo un caos. La unica recomendacion que puedo hacer aquí es que tus clases solo deben ser usadas para dar estilos y nada más que eso. Y si necesitas alguna clase para hacer algo con javascript la recomendación es que crees otra clase y le pongas al inicio “js-”

Ejemplo: js-drapdrop , js-list-autocomplete , js-grid

Cualquier clase que no comience con “js-” ya sabemos que solo es para dar estilo nada mas y podremos removerla o cambiar el nombre con confianza.


Metodologías CSS


Ahora solo nos falta por hablar sobre algunas metodologías CSS para nombrar clases, las cuales pueden ser muy útiles para escribir un código limpio. Las metodologías CSS son en palabras sencillas, consejos para estructurar mejor nuestro código CSS con el fin de que sea mantenible y escalable.

Existen muchas metodologías para escoger : OOCSSSMACSSBEM solo para nombrar algunas. Yo quiero hablar sobre BEM.

BEM es una metodología que consiste en : “block , element , modifier”. Sugiere escribir tu código CSS de manera estructural basado en elementos y modificadores. Usando BEM no esta permitido usar Ids. Ejemplo:

.block {}
.block__element {}
.block--modifier {}

block : define un bloque que contiene elementos
block__element : elementos que componen al bloque
block--modifier : reglas que modifican el estilo del bloque, ya sea estilo de presentación, posicion ó maquetado.

Para entender mejor esto veamos la siguiente imagen:

Caja de busqueda

En la imagen podemos ver una caja de búsqueda y un botón, esto es considerado un block y todos los elementos dentro de él son parte de este block. Siguiendo la metodología BEM podemos escribir las clases de esta manera.

.search {}
.search__input {}
.search__button {}
.search--big {}
.search--tiny {}

Hasta aquí lo más simple de BEM, no sería prudente escribir un tutorial completo sobre esto cuando en internet existen muchos y muy buenos. Si quieres saber más sobre esta metodología recomiendo leer los siguientes enlaces:


https://www.smashingmagazine.com/2016/06/battling-bem-extended-edition-common-problems-and-how-to-avoid-them/

Recuerda que BEM ó cualquier otra metodología no va a resolver todos tus problemas, son solo maneras muy poderosas de hacer nuestro código mantenible y escalable para que todos en tu equipo tengan una idea clara de cómo mejorar el actualizar y mejorar el CSS.






links