Frontal avanzado y assetic

159

description

Presentacion sobre frontales multidevice, responsive design y preprocesadores css realizada en el deSymfony del 2013

Transcript of Frontal avanzado y assetic

Page 1: Frontal avanzado y assetic
Page 2: Frontal avanzado y assetic
Page 4: Frontal avanzado y assetic

¿Qué es Ofertix?

Page 5: Frontal avanzado y assetic

¿Qué es Ofertix?

•Vendemos productos y servicios por internet

Page 6: Frontal avanzado y assetic

¿Qué es Ofertix?

•Vendemos productos y servicios por internet•A precios interesantes

Page 7: Frontal avanzado y assetic

¿Qué es Ofertix?

•Vendemos productos y servicios por internet•A precios interesantes•Tenemos varias lineas de negocio

Page 8: Frontal avanzado y assetic

¿Qué es Ofertix?

•Vendemos productos y servicios por internet•A precios interesantes•Tenemos varias lineas de negocio•Ventas Privadas, Ocio, Full Price y Tienda Física

Page 9: Frontal avanzado y assetic

¿Qué es Ofertix?

•Vendemos productos y servicios por internet•A precios interesantes•Tenemos varias lineas de negocio•Ventas Privadas, Ocio, Full Price y Tienda Física•7 años en marcha

Page 10: Frontal avanzado y assetic

¿Qué es Ofertix?

•Vendemos productos y servicios por internet•A precios interesantes•Tenemos varias lineas de negocio•Ventas Privadas, Ocio, Full Price y Tienda Física•7 años en marcha•Principalmente Symfony 1.2

Page 11: Frontal avanzado y assetic
Page 12: Frontal avanzado y assetic
Page 13: Frontal avanzado y assetic
Page 14: Frontal avanzado y assetic
Page 15: Frontal avanzado y assetic
Page 16: Frontal avanzado y assetic
Page 17: Frontal avanzado y assetic

¿Que Problemas Tenemos?

Page 18: Frontal avanzado y assetic

¿Que Problemas Tenemos?

NINGUNO. SOMOS LOS MEJORES

Page 20: Frontal avanzado y assetic

Pero...

Page 21: Frontal avanzado y assetic

Pero...

•Nuestra interfaz móvil es mejorable

Page 22: Frontal avanzado y assetic

Pero...

•Nuestra interfaz móvil es mejorable•Queremos añadir full-text search

Page 23: Frontal avanzado y assetic

Pero...

•Nuestra interfaz móvil es mejorable•Queremos añadir full-text search•Queremos mejorar lineas de negocio

Page 24: Frontal avanzado y assetic

Pero...

•Nuestra interfaz móvil es mejorable•Queremos añadir full-text search•Queremos mejorar lineas de negocio•Ya toca un lavado de cara

Page 25: Frontal avanzado y assetic

Pero...

•Nuestra interfaz móvil es mejorable•Queremos añadir full-text search•Queremos mejorar lineas de negocio•Ya toca un lavado de cara•Y de cuerpo

Page 26: Frontal avanzado y assetic
Page 27: Frontal avanzado y assetic
Page 28: Frontal avanzado y assetic
Page 29: Frontal avanzado y assetic
Page 30: Frontal avanzado y assetic
Page 31: Frontal avanzado y assetic
Page 32: Frontal avanzado y assetic
Page 33: Frontal avanzado y assetic
Page 34: Frontal avanzado y assetic
Page 37: Frontal avanzado y assetic

Solución

Re-escribir el frontal de todos nuestros sites.

http://symfony.com/logo

Page 38: Frontal avanzado y assetic

Solución

Re-escribir el frontal de todos nuestros sites.

Aplicando lo aprendido de nuestros errores

http://symfony.com/logo

Page 40: Frontal avanzado y assetic

La remodelación del site tiene muchos temas interesantes

•Cache•Reverse Proxy•No-SQL•Full-text Search•UX•Gestión de sesiones•Recolección de datos•Big Data

•Socialización•Web Services•Javascript Avanzado (MVC)•Gestión de Statics•Colas•Optimización de Carga•Balanceo de pagos•...

Page 41: Frontal avanzado y assetic

Pero hoy toca...

Page 42: Frontal avanzado y assetic

Pero hoy toca...

Mobile y otros dispositivos

Page 43: Frontal avanzado y assetic

¿Por qué?

Fuente Google Analytics 04/06/2013

Page 44: Frontal avanzado y assetic

¿Por qué?Otros

6%Android Browser

11%

Safari IOS 16%

Safari Mac4%Firefox Windows

13%

IE Explorer23%

Chrome Windows27%

Fuente Google Analytics 04/06/2013

Page 48: Frontal avanzado y assetic

Mobile Design

Page 49: Frontal avanzado y assetic

Mobile DesignDevice Centric Design

Page 50: Frontal avanzado y assetic

•Una plantilla por tipo de device a cubrir.•Una hoja de estilos por device*•Un “Javascript” por device*•Detectamos el tipo de device al servir el site•Permitimos cambiar el tipo de plantilla servida.

Mobile DesignDevice Centric Design

Page 51: Frontal avanzado y assetic

Como lo hacemos

<?phpnamespace Solilokiam\RequestListenerBundle\EventListener;

use Symfony\Component\HttpKernel\HttpKernelInterface;

use Symfony\Component\HttpKernel\Event\GetResponseEvent;

use Solilokiam\RequestListenerBundle\Detector\DeviceDetector;

class RequestListener{ public function onKernelRequest(GetResponseEvent $eve

nt)

{ $detector = new DeviceDetector();

$request = $event->getRequest();

$user_agent = $request->headers->get('user-agent');

if($detector->isMobile($user_agent))

{ $request->setRequestFormat('mobile', 'text/ht

ml');

} elseif($detector->isGameConsole($user_agent)) {

$request->setRequestFormat('game', 'text/html');

} elseif($detector->isTv($user_agent)) {

$request->setRequestFormat('tv', 'text/html');

} else { $request->setRequestFormat('html', 'text/html

');

} }}

Page 52: Frontal avanzado y assetic

<?phpnamespace Solilokiam\RequestListenerBundle\Detector;

class DeviceDetector{ //Incomplete regexs just educational purpouse;

private $mobile_device_regex = '/(alcatel|amoi|android|avantgo|blackberry|benq|cell|cricket|docomo|elaine|htc|iemobile|iphone|ipad|ipaq|ipod|j2me|java|midp|mini|mmp|mobi|motorola|nec-|nokia|palm|panasonic|philips|phone|playbook|sagem|sharp|sie-|silk|smartphone|sony|symbian|t-mobile|telus|up\.browser|up\.link|vodafone|wap|webos|wireless|xda|xoom|zte)/i'; private $game_console_device_regex = '/xbox/i'; private $tv_device_regex = '/(bravia|googletv)/i';

public function __construct() {

}

public function isMobile($user_agent) { if(preg_match($this->mobile_device_regex,$user_agent)) { return true; } else { return false; } }

public function isGameConsole($user_agent) { if(preg_match($this->game_console_device_regex,$user_agent)) { return true; } else { return false; } }

public function isTv($user_agent) { if(preg_match($this->tv_device_regex,$user_agent)) { return true; } else { return false; } }}

Como lo hacemos

Page 53: Frontal avanzado y assetic

parameters: solilokiam_request_listener.example.class: Solilokiam\RequestListenerBundle\EventListener\RequestListenerservices: solilokiam_request_listener.example: class: %solilokiam_request_listener.example.class% tags: - { name: kernel.event_listener, event: kernel.request, method: onKernelRequest }

<?php

namespace Solilokiam\FrontBundle\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\Controller;

class DefaultController extends Controller

{ public function indexAction($name)

{ $format = $this->getRequest()->getRequestFormat()

;

return $this->render('SolilokiamFrontBundle:Default:index.'.

$format.'.twig', array('name' => $name));

}}

Como lo hacemos

Page 54: Frontal avanzado y assetic
Page 57: Frontal avanzado y assetic

<?phpnamespace Solilokiam\RequestListenerBundle\EventListener;

use Symfony\Component\HttpKernel\HttpKernelInterface;use Symfony\Component\HttpKernel\Event\GetResponseEvent;use Symfony\Component\HttpKernel\HttpKernel;use Solilokiam\RequestListenerBundle\Manager\DeviceRedirectManager;use Solilokiam\RequestListenerBundle\Manager\DeviceManager;

class RequestListener{ protected $device_manager; protected $redirect_manager;

public function __construct(DeviceManager $device_manager,DeviceRedirectManager $redirect_manager) { $this->device_manager = $device_manager; $this->redirect_manager = $redirect_manager; }

public function onKernelRequest(GetResponseEvent $event) { if(HttpKernel::MASTER_REQUEST === $event->getRequestType()) { $request = $event->getRequest(); $user_agent = $request->headers->get('user-agent');

$this->device_manager->detectDevice($user_agent);

$response = $this->redirect_manager->redirectIfNeeded($request);

if($response) $event->setResponse($response);

return; } }}

Como lo hacemos (pero mejor)

Page 58: Frontal avanzado y assetic

Como lo hacemos (pero mejor)

<?phpnamespace Solilokiam\RequestListenerBundle\Manager;

use Solilokiam\RequestListenerBundle\Detector\DeviceDetector;

class DeviceManager{ const DEVICE_MOBILE = 'mobile'; const DEVICE_GAME = 'game'; const DEVICE_TV = 'tv';

protected $session;

public function __construct($session) { $this->session = $session; }

public function hasDevice() { return $this->session->has('device'); }

public function setDevice($device) { $this->session->set('device',$device); }

public function getDevice() { return $this->session->get('device'); }

public function detectDevice($user_agent)

{ $detector = new DeviceDetector();

if($detector->isMobile($user_agent))

{ $this->setDevice(self::DEVICE_MOBILE);

} elseif($detector->isGameConsole($user_agent)) {

$this->setDevice(self::DEVICE_GAME);

} elseif($detector->isTv($user_agent)) {

$this->setDevice(self::DEVICE_TV);

} }}

Page 59: Frontal avanzado y assetic

<?phpnamespace Solilokiam\RequestListenerBundle\Manager;

//use \Solilokiam\RequestListenerBundle\Manager\DeviceManager;use Symfony\Component\HttpFoundation\RedirectResponse;

class DeviceRedirectManager{ const VIEW_MOBILE = 'mobile.desymfony.local'; const VIEW_GAME = 'game.desymfony.local'; const VIEW_TV = 'tv.desymfony.local';

protected $view_type; protected $device_manager;

public function __construct(DeviceManager $manager) { $this->device_manager = $manager;

if(!$this->device_manager->hasDevice()) { $this->view_type = ''; } else { $device = $this->device_manager->getDevice();

$this->view_type = $device; } }

public function redirectIfNeeded($request) { $host = $request->getHost();

$responseUrl = null;

Como lo hacemos (pero mejor)

Page 60: Frontal avanzado y assetic

$this->view_type = $device; } }

public function redirectIfNeeded($request) { $host = $request->getHost();

$responseUrl = null;

if($host != self::VIEW_MOBILE && $this->view_type == 'mobile') { $responseUrl = $this->generateRedirectUrl($request,self::VIEW_MOBILE); }

if($host != self::VIEW_GAME && $this->view_type == 'game') { $responseUrl = $this->generateRedirectUrl($request,self::VIEW_GAME); }

if($host != self::VIEW_TV && $this->view_type == 'tv') { $responseUrl = $this->generateRedirectUrl($request,self::VIEW_TV); }

if($responseUrl !== null) { return new RedirectResponse($responseUrl); } return null; }

public function generateRedirectUrl($request,$view) { return 'http://'.$view.$request->getRequestUri(); }

}

Como lo hacemos (pero mejor)

Page 61: Frontal avanzado y assetic

<?phpnamespace Solilokiam\RequestListenerBundle\Twig;

use Symfony\Bundle\TwigBundle\TwigEngine as BaseTwigEngine;use Symfony\Bundle\FrameworkBundle\Templating\GlobalVariables;use Symfony\Component\Templating\TemplateNameParserInterface;use Symfony\Component\Config\FileLocatorInterface;use Solilokiam\RequestListenerBundle\Manager\DeviceManager;

class TwigEngine extends BaseTwigEngine{ protected $device_manager;

public function __construct(\Twig_Environment $environment, TemplateNameParserInterface $parser, FileLocatorInterface $locator, DeviceManager $device_manager) { $this->device_manager = $device_manager;

parent::__construct($environment, $parser, $locator); }

public function render($name, array $parameters = array()) { $device = $this->device_manager->getDevice();

$device_template = preg_replace("/^\w+:\w+:/", '$0'.$device.'/', $name); if ($this->exists($device_template)) { $name = $device_template; }

return parent::render($name, $parameters); }}

Como lo hacemos (pero mejor)

Page 62: Frontal avanzado y assetic

Como lo hacemos (pero mejor)

<?php

namespace Solilokiam\FrontBundle\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\Controller;

class DefaultController extends Controller{ public function indexAction($name) { return $this->render('SolilokiamFrontBundle:Default:index.html.twig', array('name' => $name)); }}

Page 64: Frontal avanzado y assetic

Misión cumplida

•Faltaría switch entre vistas•Mejor por cookies que por sesión•URL’s y otras cosas configurables

http://www.vayagif.com/169459/claro-que-si-campeon-michael-jackson-estaria-orgulloso-de-ti

Page 65: Frontal avanzado y assetic

Misión cumplida

•Faltaría switch entre vistas•Mejor por cookies que por sesión•URL’s y otras cosas configurables

https://github.com/kbond/ZenstruckMobileBundlehttps://github.com/suncat2000/MobileDetectBundle

http://www.vayagif.com/169459/claro-que-si-campeon-michael-jackson-estaria-orgulloso-de-ti

Page 66: Frontal avanzado y assetic

Ventajas

•Se ajusta mejor a las necesidades•Facilidad de cambiar/hacer cosas especiales•Más óptimo

Inconvenientes

•Mucho trabajo.•Alta posibilidad de liarla parda.•Múltiples url’s para la misma cosa

Page 67: Frontal avanzado y assetic

Responsive Design

•Una plantilla para todos los devices•Una sola hoja de estilos•Un solo javascript*•La presentación se adapta al dispositivo•Soporte a tantos devices como quieras*

Page 69: Frontal avanzado y assetic
Page 70: Frontal avanzado y assetic

Los 3 pilares del Responsive Design

Page 71: Frontal avanzado y assetic

Los 3 pilares del Responsive Design

1.Layout basado en un grid flexible

Page 72: Frontal avanzado y assetic

Los 3 pilares del Responsive Design

1.Layout basado en un grid flexible2.Imágenes y media flexibles

Page 73: Frontal avanzado y assetic

Los 3 pilares del Responsive Design

1.Layout basado en un grid flexible2.Imágenes y media flexibles3.Media Queries

Page 74: Frontal avanzado y assetic

Layout basado en un grid flexible

Page 75: Frontal avanzado y assetic

page { margin: 36px auto; width: 970px;}.blog { margin: 21px 0 0 0; width: 970px;}.blog .main { float: left; padding: 17px;

width: 678px;}.blog .other { float: right;margin: 0 21px 0 0;

width: 271px;}

Page 76: Frontal avanzado y assetic

Normas Básicas

Ningún tamaño fijado.Todo Relativo

•Width x Height•Padding•Margin•Font-Size•...

Regla de Cálculo

objetivo / contexto * 100 = resultado%

objetivo / contexto

Page 77: Frontal avanzado y assetic

.blog .main { float: left; padding: 17px;

width: 678px;}

Un Cálculo de Ejemplo

Page 78: Frontal avanzado y assetic

.blog .main { float: left; padding: 17px;

width: 678px;}

678 / 970 * 100 = 69,896907216495

Un Cálculo de Ejemplo

Page 79: Frontal avanzado y assetic

.blog .main { float: left; padding: 17px;

width: 678px;}

678 / 970 * 100 = 69,896907216495

Un Cálculo de Ejemplo

17 / 970 * 100 = 1,752577319588

Page 80: Frontal avanzado y assetic

678 / 970 * 100 = 69,896907216495

Un Cálculo de Ejemplo

17 / 970 * 100 = 1,752577319588

.blog .main { float: left;

padding: 69,896907216495%; width: 1,752577319588%;}

Page 81: Frontal avanzado y assetic

¿Y qué pasa con la tipografia?

Aplicamos la misma regla de cálculo

h1 { font-size: 24px;}h1 a { font-size: 11px;}

24 / context = ¿?

11/ context = ¿?

Page 82: Frontal avanzado y assetic

¿Y qué pasa con la tipografia?

El tamaño por defecto de la fuente suele ser 16px

Page 83: Frontal avanzado y assetic

¿Y qué pasa con la tipografia?

El tamaño por defecto de la fuente suele ser 16px

Mejor lo seteamos en nuestro fichero de reset

Page 84: Frontal avanzado y assetic

¿Y qué pasa con la tipografia?

El tamaño por defecto de la fuente suele ser 16px

body{font-size:16px;

}

Mejor lo seteamos en nuestro fichero de reset

Page 85: Frontal avanzado y assetic

¿Y qué pasa con la tipografia?

El tamaño por defecto de la fuente suele ser 16px

body{font-size:16px;

}

Mejor lo seteamos en nuestro fichero de reset

body{font-size: 100%;

}

Page 86: Frontal avanzado y assetic

¿Y qué pasa con la tipografia?

El tamaño por defecto de la fuente suele ser 16px

body{font-size:16px;

}

Mejor lo seteamos en nuestro fichero de reset

body{font-size: 100%;

}

http://meyerweb.com/eric/tools/css/reset/

Page 87: Frontal avanzado y assetic

¿Y qué pasa con la tipografia?

Aplicamos la misma regla de calculo

h1 { font-size: 24px;}h1 a { font-size: 11px;}

Page 88: Frontal avanzado y assetic

¿Y qué pasa con la tipografia?

Aplicamos la misma regla de calculo

h1 { font-size: 24px;}h1 a { font-size: 11px;}

24 / 16 = 1.5

Page 89: Frontal avanzado y assetic

¿Y qué pasa con la tipografia?

Aplicamos la misma regla de calculo

h1 { font-size: 24px;}h1 a { font-size: 11px;}

24 / 16 = 1.5

11/ 16 = 0,6875

Page 90: Frontal avanzado y assetic

¿Y qué pasa con la tipografia?

Aplicamos la misma regla de calculo

24 / 16 = 1.5

11/ 16 = 0,6875

h1 { font-size: 1.5em;}h1 a { font-size: 0.6875em;}

Page 91: Frontal avanzado y assetic

Imágenes y media flexibles

Varias Opciones:•Resize•Crop•HTML5 picture tag•Clown Car

Page 92: Frontal avanzado y assetic

Resize

img { max-width: 100%;}

Page 93: Frontal avanzado y assetic

Resize

img,embed,object,video { max-width: 100%;}

Page 94: Frontal avanzado y assetic

Resize

img,embed,object,video { max-width: 100%;}

•La solución más compatible•Ancho de Banda Poco Optimo•Renderizado en navegador poco optimo

Page 95: Frontal avanzado y assetic

Crop

.img_container { overflow: hidden;}.img_container img { display: block; max-width: auto;}

•Igual de compatible que resize•La imagen queda cortada•Ancho de banda poco optimo•Renderizado no excesivamente malo

Page 96: Frontal avanzado y assetic

HTML5 picture tag

<picture alt="Description of image subject."> <source srcset="small.jpg 1x, small-highres.jpg 2x"> <source media="(min-width: 18em)" srcset="med.jpg 1x, med-highres.jpg 2x"><source media="(min-width: 45em)" srcset="large.jpg 1x, large-highres.jpg 2x"> <img src="small.jpg" alt="Description of image subject."> </picture>

•Soporte Webkit (aunque con fallback)•Muy bueno con el ancho de banda•Muy bueno con el navegador

Page 97: Frontal avanzado y assetic

Clown Car<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 300 329" preserveAspectRatio="xMidYMid meet"><title>Clown Car Technique</title><style>svg { background-size: 100% 100%; background-repeat: no-repeat;}@media screen and (max-width: 400px) { svg { background-image: url(images/small.png"); }}@media screen and (min-width: 401px) and (max-width: 700px) { svg { background-image: url(images/medium.png); }}@media screen and (min-width: 701px) and (max-width: 1000px) { svg { background-image: url(images/big.png); }}@media screen and (min-width: 1001px) { svg { background-image: url(images/huge.png); }}</style></svg>

Page 98: Frontal avanzado y assetic

Clown Car<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 300 329" preserveAspectRatio="xMidYMid meet"><title>Clown Car Technique</title><style>svg { background-size: 100% 100%; background-repeat: no-repeat;}@media screen and (max-width: 400px) { svg { background-image: url(images/small.png"); }}@media screen and (min-width: 401px) and (max-width: 700px) { svg { background-image: url(images/medium.png); }}@media screen and (min-width: 701px) and (max-width: 1000px) { svg { background-image: url(images/big.png); }}@media screen and (min-width: 1001px) { svg { background-image: url(images/huge.png); }}</style></svg>

•Buen soporte•Buena con el ancho de banda•Buena con el navegador•Requiere de trabajo en el servidor

Page 99: Frontal avanzado y assetic

Media Queries

Desarrollado a partir de los Media Types (CSS 2)

@media screen { body { font-size: 100%; }}@media print { body { font-size: 15pt; }}

Page 100: Frontal avanzado y assetic

Media Queries

@media screen and (min-width: 1024px) { body { font-size: 100%; }}

<link rel="stylesheet" href="wide.css" media="screen and (min-width: 1024px)" />

Page 101: Frontal avanzado y assetic

Media Queries

No solamente podemos filtrar por height o width:

widthheightdevice-widthdevice-heightorientationaspect ratio

color (bit number)color-indexmonochrome(bits x pixel)resolution (dpi)scan(tv progressive o scan)grid

Page 102: Frontal avanzado y assetic

Media Queries

No solamente podemos filtrar por height o width:

widthheightdevice-widthdevice-heightorientationaspect ratio

color (bit number)color-indexmonochrome(bits x pixel)resolution (dpi)scan(tv progressive o scan)grid

@media screen and (min-device-width: 480px) and (orientation: landscape) { ... }

Page 103: Frontal avanzado y assetic

Media Queries

Arreglar todas las cosas que no se acaban de adaptar con Layout basado en un grid flexible

Page 104: Frontal avanzado y assetic

Media Queries

Arreglar todas las cosas que no se acaban de adaptar con Layout basado en un grid flexible

Cambiar tipografiasModificar layout

Mostrar / Ocultar elementos...

Page 105: Frontal avanzado y assetic

Ventajas

•Menos trabajo de crear vistas•Menos posibilidad de liarla•Mejor adaptabilidad ante nuevos devices•Mejor SEO

Inconvenientes

•Mucho trabajo al maquetar•No muy óptimo

Page 109: Frontal avanzado y assetic

Preprocesadores CSS

•Ahorro de muchas horas de maquetación•Cambios Rápidos•Código Estructurado

Assetic los integra perfectamente en nuestros proyectos.

Page 110: Frontal avanzado y assetic

Instalar nodeJS + npm$ npm install less

Symfony

Page 111: Frontal avanzado y assetic

Instalar nodeJS + npm$ npm install less

assetic: filters: cssrewrite: ~ less: node: /usr/local/bin/node node_paths: [/usr/local/lib/node_modules]

Symfony

Page 112: Frontal avanzado y assetic

Instalar nodeJS + npm$ npm install less

assetic: filters: cssrewrite: ~ less: node: /usr/local/bin/node node_paths: [/usr/local/lib/node_modules]

{% block stylesheets %}{% stylesheets 'less/main.less' filter='less' output='css/main.css'%}<link rel="stylesheet" href="{{ asset_url }}">{% endstylesheets %}

Symfony

Page 113: Frontal avanzado y assetic

assetic: filters: cssrewrite: ~ less: node: /usr/local/bin/node node_paths: [/usr/local/lib/node_modules] yui_css: jar: "%kernel.root_dir%/Resources/java/yuicompressor.jar"

Symfony

Page 114: Frontal avanzado y assetic

assetic: filters: cssrewrite: ~ less: node: /usr/local/bin/node node_paths: [/usr/local/lib/node_modules] yui_css: jar: "%kernel.root_dir%/Resources/java/yuicompressor.jar"

{% block stylesheets %}{% stylesheets 'less/main.less' filter='less,?yui_css’ output='css/main.css'%}<link rel="stylesheet" href="{{ asset_url }}">{% endstylesheets %}

Symfony

Page 115: Frontal avanzado y assetic

./app/console assetic:dump --env=prod --no-debug

Symfony

Page 116: Frontal avanzado y assetic

Variables

@azul: #5B83AD;@azul-claro: (@azul + #111);

#header { color: @azul-claro; }

Page 117: Frontal avanzado y assetic

Variables

@azul: #5B83AD;@azul-claro: (@azul + #111);

#header { color: @azul-claro; }

#header { color: #6c94be; }

Page 118: Frontal avanzado y assetic

Variables

@azul: #5B83AD;@azul-claro: (@azul + #111);

#header { color: @azul-claro; }

#header { color: #6c94be; }

•Scope de las variables igual que CSS•No han de ser declaradas antes de ser utilizadas

Page 119: Frontal avanzado y assetic

Variables

@azul: #5B83AD;@azul-claro: (@azul + #111);

#header { color: @azul-claro; }

#header { color: #6c94be; }

•Scope de las variables igual que CSS•No han de ser declaradas antes de ser utilizadas

@less-mola: "Less Mola";@var: 'less-mola';content: @@var;

Page 120: Frontal avanzado y assetic

Variables

@azul: #5B83AD;@azul-claro: (@azul + #111);

#header { color: @azul-claro; }

#header { color: #6c94be; }

•Scope de las variables igual que CSS•No han de ser declaradas antes de ser utilizadas

@less-mola: "Less Mola";@var: 'less-mola';content: @@var;

content: "Less Mola";

Page 121: Frontal avanzado y assetic

Mixins

.bordered { border-top: dotted 1px black; border-bottom: solid 2px black;}#menu a { color: #111; .bordered;}

Page 122: Frontal avanzado y assetic

Mixins

.bordered { border-top: dotted 1px black; border-bottom: solid 2px black;}#menu a { color: #111; .bordered;}

#menu a { color: #111; border-top: dotted 1px black; border-bottom: solid 2px black;}

Page 123: Frontal avanzado y assetic

Mixins

.bordered { border-top: dotted 1px black; border-bottom: solid 2px black;}#menu a { color: #111; .bordered;}

#menu a { color: #111; border-top: dotted 1px black; border-bottom: solid 2px black;}

.border-radius (@radius: 5px) { border-radius: @radius; -moz-border-radius: @radius; -webkit-border-radius: @radius;}#header { .border-radius(4px);}.button { .border-radius;}

Page 124: Frontal avanzado y assetic

Mixins

.bordered { border-top: dotted 1px black; border-bottom: solid 2px black;}#menu a { color: #111; .bordered;}

#menu a { color: #111; border-top: dotted 1px black; border-bottom: solid 2px black;}

.border-radius (@radius: 5px) { border-radius: @radius; -moz-border-radius: @radius; -webkit-border-radius: @radius;}#header { .border-radius(4px);}.button { .border-radius;}

#header{ border-radius: 4px; -moz-border-radius: 4px; -webkit-border-radius: 4px;}

.button { border-radius: 5px; -moz-border-radius: 5px; -webkit-border-radius: 5px;}

Page 125: Frontal avanzado y assetic

Mixins

Multiples Parametros separados por semicolon

Page 126: Frontal avanzado y assetic

Mixins

Multiples Parametros separados por semicolon

Less permite sobrecarga en los mixins

Page 127: Frontal avanzado y assetic

Mixins

Multiples Parametros separados por semicolon

Less permite sobrecarga en los mixins

.test_mixin(@width) { width: @width;}.test_mixin(@width; @color:#000000) { width-2: @width; color: @padding;}.test_mixin(@width; @color; @margin: 2) { width-3: @color; color-3: @padding; margin: @margin @margin @margin @margin;}.test div { .test_mixin(15px);}

Page 128: Frontal avanzado y assetic

Mixins

Multiples Parametros separados por semicolon

Less permite sobrecarga en los mixins

.test_mixin(@width) { width: @width;}.test_mixin(@width; @color:#000000) { width-2: @width; color: @padding;}.test_mixin(@width; @color; @margin: 2) { width-3: @color; color-3: @padding; margin: @margin @margin @margin @margin;}.test div { .test_mixin(15px);}

.test div { width: 15px; width-2: 15px; color: #000000;}

Page 129: Frontal avanzado y assetic

Mixins

.margin_mixin(@top; @right; @down; @left) { margin: @arguments;}.margin_mixin(2px; 5px;2px;5px);

Page 130: Frontal avanzado y assetic

Mixins

.margin_mixin(@top; @right; @down; @left) { margin: @arguments;}.margin_mixin(2px; 5px;2px;5px);

margin: 2px 5px 2px 5px;

Page 131: Frontal avanzado y assetic

!important

.test_mixin (@a: 0) { margin: @a; padding: @a;}.no_importante { .test_mixin(1); }.muy_importante { .test_mixin(2) !important; }

Page 132: Frontal avanzado y assetic

!important

.test_mixin (@a: 0) { margin: @a; padding: @a;}.no_importante { .test_mixin(1); }.muy_importante { .test_mixin(2) !important; }

.no_importante { margin: 1px; padding: 1px;}.muy_importante { margin: 2px !important; padding: 2px !important;}

Page 133: Frontal avanzado y assetic

Nested Rules

#header { color: black; }#header .navigation { font-size: 12px;}#header .logo { width: 300px;}#header .logo:hover { text-decoration: none;}

Page 134: Frontal avanzado y assetic

Nested Rules

#header { color: black; }#header .navigation { font-size: 12px;}#header .logo { width: 300px;}#header .logo:hover { text-decoration: none;}

#header { color: black; .navigation { font-size: 12px } .logo { width: 300px; &:hover { text-decoration: none } }}

Page 135: Frontal avanzado y assetic

Operations

•Afectan a numeros y colores•Tienen que ir entre paréntesis

Page 136: Frontal avanzado y assetic

Operations

•Afectan a numeros y colores•Tienen que ir entre paréntesis@context: 970

.blog .main { float: left;padding: percentage((679px / @context));

width: percentage((17px / @context));

}

Page 137: Frontal avanzado y assetic

Operations

•Afectan a numeros y colores•Tienen que ir entre paréntesis@context: 970

.blog .main { float: left;padding: percentage((679px / @context));

width: percentage((17px / @context));

}

.blog .main { float: left;

padding: 69,896907216495%; width: 1,752577319588%;}

Page 138: Frontal avanzado y assetic

Importing

@import "test.css";

Page 139: Frontal avanzado y assetic

Importing

@import "test.css"; @import "library.less";

Page 140: Frontal avanzado y assetic

Importing

@import "test.css"; @import "library.less";

@imported-color: red;h1 { color: green; }

@import "library.less" screen and (max-width: 400px);@import "library.less";

.class { color: @importedColor;}

Page 141: Frontal avanzado y assetic

Importing

@import "test.css"; @import "library.less";

@imported-color: red;h1 { color: green; }

@import "library.less" screen and (max-width: 400px);@import "library.less";

.class { color: @importedColor;}

@media screen and (max-width: 400px) { h1 { color: green; }}

h1 { color: green; }.class { // Use imported variable color: #ff0000;}

Page 142: Frontal avanzado y assetic

Funciones

escape(@string); // URL encodes a stringe(@string); // escape string content%(@string, values...); // formats a string

ceil(@number); // rounds up to an integerfloor(@number); // rounds down to an integerpercentage(@number); // converts to a %, e.g. 0.5 -> 50%round(number, [places: 0]);// rounds a number to a number of places

saturate(@color, 10%); // return a color 10% points *more* saturated

desaturate(@color, 10%);// return a color 10% points *less* saturated

lighten(@color, 10%); // return a color 10% points *lighter*

darken(@color, 10%); // return a color 10% points *darker*

Page 143: Frontal avanzado y assetic

Pattern Matching

.mixin (dark; @color) { color: darken(@color, 10%);}.mixin (light; @color) { color: lighten(@color, 10%);}.mixin (@_; @color) { display: block;}

Page 144: Frontal avanzado y assetic

Pattern Matching

.mixin (dark; @color) { color: darken(@color, 10%);}.mixin (light; @color) { color: lighten(@color, 10%);}.mixin (@_; @color) { display: block;}

@switch: light;

.class { .mixin(@switch; #888);}

Page 145: Frontal avanzado y assetic

Pattern Matching

.mixin (dark; @color) { color: darken(@color, 10%);}.mixin (light; @color) { color: lighten(@color, 10%);}.mixin (@_; @color) { display: block;}

@switch: light;

.class { .mixin(@switch; #888);}

.class { color: #a2a2a2; display: block;}

Page 146: Frontal avanzado y assetic

Guarded Params

.mixin (@a) when (lightness(@a) >= 50%) { background-color: black;}.mixin (@a) when (lightness(@a) < 50%) { background-color: white;}.mixin (@a) { color: @a;}

Page 147: Frontal avanzado y assetic

Guarded Params

.mixin (@a) when (lightness(@a) >= 50%) { background-color: black;}.mixin (@a) when (lightness(@a) < 50%) { background-color: white;}.mixin (@a) { color: @a;}

.class1 { .mixin(#ddd) }

.class2 { .mixin(#555) }

Page 148: Frontal avanzado y assetic

Guarded Params

.mixin (@a) when (lightness(@a) >= 50%) { background-color: black;}.mixin (@a) when (lightness(@a) < 50%) { background-color: white;}.mixin (@a) { color: @a;}

.class1 { .mixin(#ddd) }

.class2 { .mixin(#555) }

.class1 { background-color: black; color: #ddd;}.class2 { background-color: white; color: #555;}

Page 149: Frontal avanzado y assetic

Comentarios

/* Hola soy un comentario la mar de interesante */.test_class { color: #008866 }

Page 150: Frontal avanzado y assetic

Comentarios

/* Hola soy un comentario la mar de interesante */.test_class { color: #008866 }

/* Hola soy un comentario la mar de interesante */.test_class { color: #008866 }

Page 151: Frontal avanzado y assetic

Comentarios

/* Hola soy un comentario la mar de interesante */.test_class { color: #008866 }

/* Hola soy un comentario la mar de interesante */.test_class { color: #008866 }

//Hola soy un comentario que mejor no salga en produccion.test_class { color: #008866 }

Page 152: Frontal avanzado y assetic

Comentarios

/* Hola soy un comentario la mar de interesante */.test_class { color: #008866 }

/* Hola soy un comentario la mar de interesante */.test_class { color: #008866 }

//Hola soy un comentario que mejor no salga en produccion.test_class { color: #008866 }

.test_class { color: #008866 }

Page 156: Frontal avanzado y assetic

Quiero saber más.

http://lesscss.org http://twitter.github.io/bootstrap/

http://lesshat.com/

¿Qué pasa con SASS?

•Más completo que less•Peor documentación•Mismos principios•Hecho en ruby•Ultimamente menos activo

http://sass-lang.com/

http://compass-style.org/

http://foundation.zurb.com/

Page 157: Frontal avanzado y assetic

Resumiendo

•Adaptad vuestra aplicación a varios devices•Analizad vuestras necesidades•Aplicad la técnica que mejor os vaya•Utilizad preprocesadores de CSS