Frontal avanzado y assetic
Upcoming SlideShare
Loading in...5
×
 

Like this? Share it with your network

Share

Frontal avanzado y assetic

on

  • 1,634 views

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

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

Statistics

Views

Total Views
1,634
Views on SlideShare
758
Embed Views
876

Actions

Likes
2
Downloads
34
Comments
0

8 Embeds 876

http://librosweb.es 370
http://desymfony.com 335
https://twitter.com 66
http://www.desymfony.com 63
http://www.solilokiam.com 35
http://desymfony.local 3
https://www.linkedin.com 3
http://www.linkedin.com 1
More...

Accessibility

Categories

Upload Details

Uploaded via as Adobe PDF

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

Frontal avanzado y assetic Presentation Transcript

  • 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. ¿Qué es Ofertix?
  • 3. ¿Qué es Ofertix?•Vendemos productos y servicios por internet
  • 4. ¿Qué es Ofertix?•Vendemos productos y servicios por internet•A precios interesantes
  • 5. ¿Qué es Ofertix?•Vendemos productos y servicios por internet•A precios interesantes•Tenemos varias lineas de negocio
  • 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. ¿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. ¿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. ¿Que Problemas Tenemos?
  • 10. ¿Que Problemas Tenemos?NINGUNO.SOMOS LOS MEJORES
  • 11. ¿Que Problemas Tenemos?NINGUNO.SOMOS LOS MEJOREShttp://miexesunameme.blogspot.com.es/2013/05/mientras-tanto-en-clase.html
  • 12. Pero...
  • 13. Pero...•Nuestra interfaz móvil es mejorable
  • 14. Pero...•Nuestra interfaz móvil es mejorable•Queremos añadir full-text search
  • 15. Pero...•Nuestra interfaz móvil es mejorable•Queremos añadir full-text search•Queremos mejorar lineas de negocio
  • 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. 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. http://www.youtube.com/watch?v=PDXrXBsTFSE
  • 19. Soluciónhttp://symfony.com/logo
  • 20. SoluciónRe-escribir el frontal de todos nuestros sites.http://symfony.com/logo
  • 21. SoluciónRe-escribir el frontal de todos nuestros sites.Aplicando lo aprendido de nuestros erroreshttp://symfony.com/logo
  • 22. Soluciónhttp://symfony.com/logo
  • 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. Pero hoy toca...
  • 25. Pero hoy toca...Mobile y otros dispositivos
  • 26. ¿Por qué?Fuente Google Analytics 04/06/2013
  • 27. ¿Por qué?Otros6%Android Browser11%Safari IOS16%Safari Mac4%Firefox Windows13%IE Explorer23%Chrome Windows27%Fuente Google Analytics 04/06/2013
  • 28. Dos posibles solucioneshttp://www.webdesignshock.com/responsive-design/http://www.betsmartmedia.com/wp-content/themes/scope/images/svg/fallback/iphone.png
  • 29. Dos posibles solucioneshttp://www.webdesignshock.com/responsive-design/http://www.betsmartmedia.com/wp-content/themes/scope/images/svg/fallback/iphone.pngMobile Site
  • 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. Mobile Design
  • 32. Mobile DesignDevice Centric Design
  • 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. 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. <?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. 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. Buscamos Programadoreshttp://alba-twist.blogspot.com.es/2011_10_01_archive.html
  • 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. <?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. 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. <?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. 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. <?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. 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. Misión cumplidahttp://www.vayagif.com/169459/claro-que-si-campeon-michael-jackson-estaria-orgulloso-de-ti
  • 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. 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. 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. 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. ¿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. Los 3 pilares del Responsive Design
  • 52. Los 3 pilares del Responsive Design1.Layout basado en un grid flexible
  • 53. Los 3 pilares del Responsive Design1.Layout basado en un grid flexible2.Imágenes y media flexibles
  • 54. Los 3 pilares del Responsive Design1.Layout basado en un grid flexible2.Imágenes y media flexibles3.Media Queries
  • 55. Layout basado en un grid flexible
  • 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. 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. .blog .main {float: left;padding: 17px;width: 678px;}Un Cálculo de Ejemplo
  • 59. .blog .main {float: left;padding: 17px;width: 678px;}678 / 970 * 100 = 69,896907216495Un Cálculo de Ejemplo
  • 60. .blog .main {float: left;padding: 17px;width: 678px;}678 / 970 * 100 = 69,896907216495Un Cálculo de Ejemplo17 / 970 * 100 = 1,752577319588
  • 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. ¿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. ¿Y qué pasa con la tipografia?El tamaño por defecto de la fuente suele ser 16px
  • 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. ¿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. ¿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. ¿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. ¿Y qué pasa con la tipografia?Aplicamos la misma regla de calculoh1 {font-size: 24px;}h1 a {font-size: 11px;}
  • 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. ¿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. ¿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. Imágenes y media flexiblesVarias Opciones:•Resize•Crop•HTML5 picture tag•Clown Car
  • 73. Resizeimg {max-width: 100%;}
  • 74. Resizeimg,embed,object,video {max-width: 100%;}
  • 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. 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. 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. 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. 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. Media QueriesDesarrollado a partir de los MediaTypes (CSS 2)@media screen {body {font-size: 100%;}}@media print {body {font-size: 15pt;}}
  • 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. 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. 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. Media QueriesArreglar todas las cosas que no se acaban de adaptar conLayout basado en un grid flexible
  • 85. Media QueriesArreglar todas las cosas que no se acaban de adaptar conLayout basado en un grid flexibleCambiar tipografiasModificar layoutMostrar / Ocultar elementos...
  • 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. http://www.youtube.com/watch?v=pDUH1Pjl5Sk
  • 88. http://www.abookapart.com/products/responsive-web-designhttp://www.youtube.com/watch?v=pDUH1Pjl5Sk
  • 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. Preprocesadores CSS•Ahorro de muchas horas de maquetación•Cambios Rápidos•Código EstructuradoAssetic los integra perfectamente en nuestros proyectos.
  • 91. Instalar nodeJS + npm$ npm install lessSymfony
  • 92. Instalar nodeJS + npm$ npm install lessassetic:filters:cssrewrite: ~less:node: /usr/local/bin/nodenode_paths: [/usr/local/lib/node_modules]Symfony
  • 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. 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. 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. ./app/console assetic:dump --env=prod --no-debugSymfony
  • 97. Variables@azul: #5B83AD;@azul-claro: (@azul + #111);#header { color: @azul-claro; }
  • 98. Variables@azul: #5B83AD;@azul-claro: (@azul + #111);#header { color: @azul-claro; }#header { color: #6c94be; }
  • 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. 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. 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. Mixins.bordered {border-top: dotted 1px black;border-bottom: solid 2px black;}#menu a {color: #111;.bordered;}
  • 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. 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. 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. MixinsMultiples Parametros separados por semicolon
  • 107. MixinsMultiples Parametros separados por semicolonLess permite sobrecarga en los mixins
  • 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. 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. Mixins.margin_mixin(@top; @right; @down; @left){margin: @arguments;}.margin_mixin(2px; 5px;2px;5px);
  • 111. Mixins.margin_mixin(@top; @right; @down; @left){margin: @arguments;}.margin_mixin(2px; 5px;2px;5px);margin: 2px 5px 2px 5px;
  • 112. !important.test_mixin (@a: 0) {margin: @a;padding: @a;}.no_importante {.test_mixin(1);}.muy_importante {.test_mixin(2) !important;}
  • 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. Nested Rules#header { color: black; }#header .navigation {font-size: 12px;}#header .logo {width: 300px;}#header .logo:hover {text-decoration: none;}
  • 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. Operations•Afectan a numeros y colores•Tienen que ir entre paréntesis
  • 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. 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. Importing@import "test.css";
  • 120. Importing@import "test.css"; @import "library.less";
  • 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. 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. 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. Pattern Matching.mixin (dark; @color) {color: darken(@color, 10%);}.mixin (light; @color) {color: lighten(@color, 10%);}.mixin (@_; @color) {display: block;}
  • 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. 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. 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. 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. 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. Comentarios/* Hola soy un comentario la mar de interesante */.test_class { color: #008866 }
  • 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. 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. 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. Quiero saber más.http://lesscss.org http://twitter.github.io/bootstrap/http://lesshat.com/
  • 135. Quiero saber más.http://lesscss.org http://twitter.github.io/bootstrap/http://lesshat.com/¿Qué pasa con SASS?
  • 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. 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. Resumiendo•Adaptad vuestra aplicación a varios devices•Analizad vuestras necesidades•Aplicad la técnica que mejor os vaya•Utilizad preprocesadores de CSS
  • 139. Preguntas y respuestashttps://www.youtube.com/watch?v=Q1AZfqghL30
  • 140. Graciashttps://joind.in/8841