Frontal avanzado y assetic

2,101 views

Published on

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

Published in: Technology
0 Comments
2 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
2,101
On SlideShare
0
From Embeds
0
Number of Embeds
984
Actions
Shares
0
Downloads
40
Comments
0
Likes
2
Embeds 0
No embeds

No notes for slide

Frontal avanzado y assetic

  1. 1. ¿Quién Soy?•Tech Lead en Ofertix.com•Apasionado de la Web•7 años en PHP•Enganchado a Symfony desde la 1.2•‘Whovian’ y Aerotrastornadomiquel@solilokiam.com@solilokiamhttp://www.github.com/solilokiam
  2. 2. ¿Qué es Ofertix?
  3. 3. ¿Qué es Ofertix?•Vendemos productos y servicios por internet
  4. 4. ¿Qué es Ofertix?•Vendemos productos y servicios por internet•A precios interesantes
  5. 5. ¿Qué es Ofertix?•Vendemos productos y servicios por internet•A precios interesantes•Tenemos varias lineas de negocio
  6. 6. ¿Qué es Ofertix?•Vendemos productos y servicios por internet•A precios interesantes•Tenemos varias lineas de negocio•Ventas Privadas, Ocio, Full Price yTienda Física
  7. 7. ¿Qué es Ofertix?•Vendemos productos y servicios por internet•A precios interesantes•Tenemos varias lineas de negocio•Ventas Privadas, Ocio, Full Price yTienda Física•7 años en marcha
  8. 8. ¿Qué es Ofertix?•Vendemos productos y servicios por internet•A precios interesantes•Tenemos varias lineas de negocio•Ventas Privadas, Ocio, Full Price yTienda Física•7 años en marcha•Principalmente Symfony 1.2
  9. 9. ¿Que Problemas Tenemos?
  10. 10. ¿Que Problemas Tenemos?NINGUNO.SOMOS LOS MEJORES
  11. 11. ¿Que Problemas Tenemos?NINGUNO.SOMOS LOS MEJOREShttp://miexesunameme.blogspot.com.es/2013/05/mientras-tanto-en-clase.html
  12. 12. Pero...
  13. 13. Pero...•Nuestra interfaz móvil es mejorable
  14. 14. Pero...•Nuestra interfaz móvil es mejorable•Queremos añadir full-text search
  15. 15. Pero...•Nuestra interfaz móvil es mejorable•Queremos añadir full-text search•Queremos mejorar lineas de negocio
  16. 16. Pero...•Nuestra interfaz móvil es mejorable•Queremos añadir full-text search•Queremos mejorar lineas de negocio•Ya toca un lavado de cara
  17. 17. 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
  18. 18. http://www.youtube.com/watch?v=PDXrXBsTFSE
  19. 19. Soluciónhttp://symfony.com/logo
  20. 20. SoluciónRe-escribir el frontal de todos nuestros sites.http://symfony.com/logo
  21. 21. SoluciónRe-escribir el frontal de todos nuestros sites.Aplicando lo aprendido de nuestros erroreshttp://symfony.com/logo
  22. 22. Soluciónhttp://symfony.com/logo
  23. 23. 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•...
  24. 24. Pero hoy toca...
  25. 25. Pero hoy toca...Mobile y otros dispositivos
  26. 26. ¿Por qué?Fuente Google Analytics 04/06/2013
  27. 27. ¿Por qué?Otros6%Android Browser11%Safari IOS16%Safari Mac4%Firefox Windows13%IE Explorer23%Chrome Windows27%Fuente Google Analytics 04/06/2013
  28. 28. Dos posibles solucioneshttp://www.webdesignshock.com/responsive-design/http://www.betsmartmedia.com/wp-content/themes/scope/images/svg/fallback/iphone.png
  29. 29. Dos posibles solucioneshttp://www.webdesignshock.com/responsive-design/http://www.betsmartmedia.com/wp-content/themes/scope/images/svg/fallback/iphone.pngMobile Site
  30. 30. Dos posibles solucioneshttp://www.webdesignshock.com/responsive-design/http://www.betsmartmedia.com/wp-content/themes/scope/images/svg/fallback/iphone.pngResponsive DesignMobile Site
  31. 31. Mobile Design
  32. 32. Mobile DesignDevice Centric Design
  33. 33. •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
  34. 34. Como lo hacemos<?phpnamespace SolilokiamRequestListenerBundleEventListener;use SymfonyComponentHttpKernelHttpKernelInterface;use SymfonyComponentHttpKernelEventGetResponseEvent;use SolilokiamRequestListenerBundleDetectorDeviceDetector;class RequestListener{public function onKernelRequest(GetResponseEvent $event){$detector = new DeviceDetector();$request = $event->getRequest();$user_agent = $request->headers->get(user-agent);if($detector->isMobile($user_agent)){$request->setRequestFormat(mobile, text/html);} 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);}}}
  35. 35. <?phpnamespace SolilokiamRequestListenerBundleDetector;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
  36. 36. parameters:solilokiam_request_listener.example.class: SolilokiamRequestListenerBundleEventListenerRequestListenerservices:solilokiam_request_listener.example:class: %solilokiam_request_listener.example.class%tags:- { name: kernel.event_listener, event: kernel.request, method: onKernelRequest }<?phpnamespace SolilokiamFrontBundleController;use SymfonyBundleFrameworkBundleControllerController;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
  37. 37. Buscamos Programadoreshttp://alba-twist.blogspot.com.es/2011_10_01_archive.html
  38. 38. Buscamos Programadores•Expertos en Symfony 2 y 1•Motivados•Con ganas de aprender y mejorar•Incorporarse en un gran equipo•Proyecto consolidado pero en mejora continua•Buenas condicionesMás Información: it@ofertix.comhttp://alba-twist.blogspot.com.es/2011_10_01_archive.html
  39. 39. <?phpnamespace SolilokiamRequestListenerBundleEventListener;use SymfonyComponentHttpKernelHttpKernelInterface;use SymfonyComponentHttpKernelEventGetResponseEvent;use SymfonyComponentHttpKernelHttpKernel;use SolilokiamRequestListenerBundleManagerDeviceRedirectManager;use SolilokiamRequestListenerBundleManagerDeviceManager;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)
  40. 40. Como lo hacemos (pero mejor)<?phpnamespace SolilokiamRequestListenerBundleManager;use SolilokiamRequestListenerBundleDetectorDeviceDetector;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);}}}
  41. 41. <?phpnamespace SolilokiamRequestListenerBundleManager;//use SolilokiamRequestListenerBundleManagerDeviceManager;use SymfonyComponentHttpFoundationRedirectResponse;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();Como lo hacemos (pero mejor)
  42. 42. 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)
  43. 43. <?phpnamespace SolilokiamRequestListenerBundleTwig;use SymfonyBundleTwigBundleTwigEngine as BaseTwigEngine;use SymfonyBundleFrameworkBundleTemplatingGlobalVariables;use SymfonyComponentTemplatingTemplateNameParserInterface;use SymfonyComponentConfigFileLocatorInterface;use SolilokiamRequestListenerBundleManagerDeviceManager;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)
  44. 44. Como lo hacemos (pero mejor)<?phpnamespace SolilokiamFrontBundleController;use SymfonyBundleFrameworkBundleControllerController;class DefaultController extends Controller{public function indexAction($name){return $this->render(SolilokiamFrontBundle:Default:index.html.twig, array(name => $name));}}
  45. 45. Misión cumplidahttp://www.vayagif.com/169459/claro-que-si-campeon-michael-jackson-estaria-orgulloso-de-ti
  46. 46. Misión cumplida•Faltaría switch entre vistas•Mejor por cookies que por sesión•URL’s y otras cosas configurableshttp://www.vayagif.com/169459/claro-que-si-campeon-michael-jackson-estaria-orgulloso-de-ti
  47. 47. Misión cumplida•Faltaría switch entre vistas•Mejor por cookies que por sesión•URL’s y otras cosas configurableshttps://github.com/kbond/ZenstruckMobileBundlehttps://github.com/suncat2000/MobileDetectBundlehttp://www.vayagif.com/169459/claro-que-si-campeon-michael-jackson-estaria-orgulloso-de-ti
  48. 48. Ventajas•Se ajusta mejor a las necesidades•Facilidad de cambiar/hacer cosas especiales•Más óptimoInconvenientes•Mucho trabajo.•Alta posibilidad de liarla parda.•Múltiples url’s para la misma cosa
  49. 49. 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*
  50. 50. ¿Qué es Responsive Design?Responsive Web design is theapproach that suggests thatdesign and development shouldrespond to the user’s behaviorand environment based on screensize, platform and orientation.Kayla Knight @KaylaMaeKnight
  51. 51. Los 3 pilares del Responsive Design
  52. 52. Los 3 pilares del Responsive Design1.Layout basado en un grid flexible
  53. 53. Los 3 pilares del Responsive Design1.Layout basado en un grid flexible2.Imágenes y media flexibles
  54. 54. Los 3 pilares del Responsive Design1.Layout basado en un grid flexible2.Imágenes y media flexibles3.Media Queries
  55. 55. Layout basado en un grid flexible
  56. 56. 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;}
  57. 57. Normas BásicasNingún tamaño fijado.Todo Relativo•Width x Height•Padding•Margin•Font-Size•...Regla de Cálculoobjetivo / contexto * 100 = resultado%objetivo / contexto
  58. 58. .blog .main {float: left;padding: 17px;width: 678px;}Un Cálculo de Ejemplo
  59. 59. .blog .main {float: left;padding: 17px;width: 678px;}678 / 970 * 100 = 69,896907216495Un Cálculo de Ejemplo
  60. 60. .blog .main {float: left;padding: 17px;width: 678px;}678 / 970 * 100 = 69,896907216495Un Cálculo de Ejemplo17 / 970 * 100 = 1,752577319588
  61. 61. 678 / 970 * 100 = 69,896907216495Un Cálculo de Ejemplo17 / 970 * 100 = 1,752577319588.blog .main {float: left;padding: 69,896907216495%;width: 1,752577319588%;}
  62. 62. ¿Y qué pasa con la tipografia?Aplicamos la misma regla de cálculoh1 {font-size: 24px;}h1 a {font-size: 11px;}24 / context = ¿?11/ context = ¿?
  63. 63. ¿Y qué pasa con la tipografia?El tamaño por defecto de la fuente suele ser 16px
  64. 64. ¿Y qué pasa con la tipografia?El tamaño por defecto de la fuente suele ser 16pxMejor lo seteamos en nuestro fichero de reset
  65. 65. ¿Y qué pasa con la tipografia?El tamaño por defecto de la fuente suele ser 16pxbody{font-size:16px;}Mejor lo seteamos en nuestro fichero de reset
  66. 66. ¿Y qué pasa con la tipografia?El tamaño por defecto de la fuente suele ser 16pxbody{font-size:16px;}Mejor lo seteamos en nuestro fichero de resetbody{font-size: 100%;}
  67. 67. ¿Y qué pasa con la tipografia?El tamaño por defecto de la fuente suele ser 16pxbody{font-size:16px;}Mejor lo seteamos en nuestro fichero de resetbody{font-size: 100%;}http://meyerweb.com/eric/tools/css/reset/
  68. 68. ¿Y qué pasa con la tipografia?Aplicamos la misma regla de calculoh1 {font-size: 24px;}h1 a {font-size: 11px;}
  69. 69. ¿Y qué pasa con la tipografia?Aplicamos la misma regla de calculoh1 {font-size: 24px;}h1 a {font-size: 11px;}24 / 16 = 1.5
  70. 70. ¿Y qué pasa con la tipografia?Aplicamos la misma regla de calculoh1 {font-size: 24px;}h1 a {font-size: 11px;}24 / 16 = 1.511/ 16 = 0,6875
  71. 71. ¿Y qué pasa con la tipografia?Aplicamos la misma regla de calculo24 / 16 = 1.511/ 16 = 0,6875h1 {font-size: 1.5em;}h1 a {font-size: 0.6875em;}
  72. 72. Imágenes y media flexiblesVarias Opciones:•Resize•Crop•HTML5 picture tag•Clown Car
  73. 73. Resizeimg {max-width: 100%;}
  74. 74. Resizeimg,embed,object,video {max-width: 100%;}
  75. 75. Resizeimg,embed,object,video {max-width: 100%;}•La solución más compatible•Ancho de Banda Poco Optimo•Renderizado en navegador poco optimo
  76. 76. 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
  77. 77. 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
  78. 78. 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>
  79. 79. 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
  80. 80. Media QueriesDesarrollado a partir de los MediaTypes (CSS 2)@media screen {body {font-size: 100%;}}@media print {body {font-size: 15pt;}}
  81. 81. Media Queries@media screen and (min-width: 1024px) {body {font-size: 100%;}}<link rel="stylesheet" href="wide.css" media="screen and (min-width: 1024px)" />
  82. 82. Media QueriesNo solamente podemos filtrar por height o width:widthheightdevice-widthdevice-heightorientationaspect ratiocolor (bit number)color-indexmonochrome(bits x pixel)resolution (dpi)scan(tv progressive o scan)grid
  83. 83. Media QueriesNo solamente podemos filtrar por height o width:widthheightdevice-widthdevice-heightorientationaspect ratiocolor (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) { ... }
  84. 84. Media QueriesArreglar todas las cosas que no se acaban de adaptar conLayout basado en un grid flexible
  85. 85. Media QueriesArreglar todas las cosas que no se acaban de adaptar conLayout basado en un grid flexibleCambiar tipografiasModificar layoutMostrar / Ocultar elementos...
  86. 86. Ventajas•Menos trabajo de crear vistas•Menos posibilidad de liarla•Mejor adaptabilidad ante nuevos devices•Mejor SEOInconvenientes•Mucho trabajo al maquetar•No muy óptimo
  87. 87. http://www.youtube.com/watch?v=pDUH1Pjl5Sk
  88. 88. http://www.abookapart.com/products/responsive-web-designhttp://www.youtube.com/watch?v=pDUH1Pjl5Sk
  89. 89. http://www.abookapart.com/products/responsive-web-designhttp://www.youtube.com/watch?v=pDUH1Pjl5Skhttp://twitter.github.io/bootstrap/http://foundation.zurb.com/http://www.getskeleton.com/
  90. 90. Preprocesadores CSS•Ahorro de muchas horas de maquetación•Cambios Rápidos•Código EstructuradoAssetic los integra perfectamente en nuestros proyectos.
  91. 91. Instalar nodeJS + npm$ npm install lessSymfony
  92. 92. Instalar nodeJS + npm$ npm install lessassetic:filters:cssrewrite: ~less:node: /usr/local/bin/nodenode_paths: [/usr/local/lib/node_modules]Symfony
  93. 93. Instalar nodeJS + npm$ npm install lessassetic:filters:cssrewrite: ~less:node: /usr/local/bin/nodenode_paths: [/usr/local/lib/node_modules]{% block stylesheets %}{% stylesheetsless/main.lessfilter=lessoutput=css/main.css%}<link rel="stylesheet" href="{{ asset_url }}">{% endstylesheets %}Symfony
  94. 94. assetic:filters:cssrewrite: ~less:node: /usr/local/bin/nodenode_paths: [/usr/local/lib/node_modules]yui_css:jar: "%kernel.root_dir%/Resources/java/yuicompressor.jar"Symfony
  95. 95. assetic:filters:cssrewrite: ~less:node: /usr/local/bin/nodenode_paths: [/usr/local/lib/node_modules]yui_css:jar: "%kernel.root_dir%/Resources/java/yuicompressor.jar"{% block stylesheets %}{% stylesheetsless/main.lessfilter=less,?yui_css’output=css/main.css%}<link rel="stylesheet" href="{{ asset_url }}">{% endstylesheets %}Symfony
  96. 96. ./app/console assetic:dump --env=prod --no-debugSymfony
  97. 97. Variables@azul: #5B83AD;@azul-claro: (@azul + #111);#header { color: @azul-claro; }
  98. 98. Variables@azul: #5B83AD;@azul-claro: (@azul + #111);#header { color: @azul-claro; }#header { color: #6c94be; }
  99. 99. 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
  100. 100. 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;
  101. 101. 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";
  102. 102. Mixins.bordered {border-top: dotted 1px black;border-bottom: solid 2px black;}#menu a {color: #111;.bordered;}
  103. 103. 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 2pxblack;}
  104. 104. 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 2pxblack;}.border-radius (@radius: 5px) {border-radius: @radius;-moz-border-radius: @radius;-webkit-border-radius: @radius;}#header {.border-radius(4px);}.button {.border-radius;}
  105. 105. 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 2pxblack;}.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;}
  106. 106. MixinsMultiples Parametros separados por semicolon
  107. 107. MixinsMultiples Parametros separados por semicolonLess permite sobrecarga en los mixins
  108. 108. MixinsMultiples Parametros separados por semicolonLess 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);}
  109. 109. MixinsMultiples Parametros separados por semicolonLess 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;}
  110. 110. Mixins.margin_mixin(@top; @right; @down; @left){margin: @arguments;}.margin_mixin(2px; 5px;2px;5px);
  111. 111. Mixins.margin_mixin(@top; @right; @down; @left){margin: @arguments;}.margin_mixin(2px; 5px;2px;5px);margin: 2px 5px 2px 5px;
  112. 112. !important.test_mixin (@a: 0) {margin: @a;padding: @a;}.no_importante {.test_mixin(1);}.muy_importante {.test_mixin(2) !important;}
  113. 113. !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;}
  114. 114. Nested Rules#header { color: black; }#header .navigation {font-size: 12px;}#header .logo {width: 300px;}#header .logo:hover {text-decoration: none;}
  115. 115. 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 }}}
  116. 116. Operations•Afectan a numeros y colores•Tienen que ir entre paréntesis
  117. 117. 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));}
  118. 118. 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%;}
  119. 119. Importing@import "test.css";
  120. 120. Importing@import "test.css"; @import "library.less";
  121. 121. 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;}
  122. 122. 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 variablecolor: #ff0000;}
  123. 123. Funcionesescape(@string); // URL encodes a stringe(@string); // escape string content%(@string, values...); // formats a stringceil(@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 placessaturate(@color, 10%); // return a color 10% points *more* saturateddesaturate(@color, 10%);// return a color 10% points *less* saturatedlighten(@color, 10%); // return a color 10% points *lighter*darken(@color, 10%); // return a color 10% points *darker*
  124. 124. Pattern Matching.mixin (dark; @color) {color: darken(@color, 10%);}.mixin (light; @color) {color: lighten(@color, 10%);}.mixin (@_; @color) {display: block;}
  125. 125. 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);}
  126. 126. 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;}
  127. 127. Guarded Params.mixin (@a) when (lightness(@a) >= 50%) {background-color: black;}.mixin (@a) when (lightness(@a) < 50%) {background-color: white;}.mixin (@a) {color: @a;}
  128. 128. 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) }
  129. 129. 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;}
  130. 130. Comentarios/* Hola soy un comentario la mar de interesante */.test_class { color: #008866 }
  131. 131. 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 }
  132. 132. 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 }
  133. 133. 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 }
  134. 134. Quiero saber más.http://lesscss.org http://twitter.github.io/bootstrap/http://lesshat.com/
  135. 135. Quiero saber más.http://lesscss.org http://twitter.github.io/bootstrap/http://lesshat.com/¿Qué pasa con SASS?
  136. 136. 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
  137. 137. 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 activohttp://sass-lang.com/http://compass-style.org/http://foundation.zurb.com/
  138. 138. Resumiendo•Adaptad vuestra aplicación a varios devices•Analizad vuestras necesidades•Aplicad la técnica que mejor os vaya•Utilizad preprocesadores de CSS
  139. 139. Preguntas y respuestashttps://www.youtube.com/watch?v=Q1AZfqghL30
  140. 140. Graciashttps://joind.in/8841

×