LESS - CSS dla leniwych
Tomasz Dziuda Główny programista w GavickPro dziudek@gmail.com Twitter: @dziudek zebymniezapomnial.tumblr.com
Czym jest LESS?
Alternatywy 1. SASS (Ruby) 2. Turbine (PHP) 3. CSS Preprocessor (PHP) 4. Stylus (JavaScript)
Dlaczego warto poznać LESS? Popularność (np. Bootstrap, Joomla!) Ponowne wykorzystanie kodu Udostępnia to czego nie ma (a powinien) CSS Dobry na początek przygody z preprocessorami CSS
Zalety LESS 1. Łatwe zarządzanie kolorami, rozmiarami tekstu etc. 2. Pozwala zapomnieć o vendor prefixes 3. Zmniejszenie liczby plików CSS 4. Łatwiejsze tworzenie dedykowanych plików CSS dla wybranych podstron
Wady LESS Wymaga dodatkowego kroku przy pracy z plikami Może powodować problemy ze znalezieniem odpowiedniego fragmentu kodu w Chrome Dev Tools czy Firebugu Nieumiejętnie stosowany może wygenerować sporo nadmiarowego kodu CSS. Wciąż brakuje mu wielu udogodnień znanych np. z SASS
IE a duże pliki CSS Przy korzystaniu z jednego pliku warto pamiętać, że IE < 10 ma limit 4095 selektorów w jednym pliku: http://marc.baffl.co.uk/browser_bugs/css-selector-limit/
Workflow przy LESS Ręcznie Automatycznie
Narzędzia pomocnicze LESS.app less.js PHPLESS http://less2css.org/ http://incident57.com/codekit/
Brackets Dzięki rozszerzeniu BracktesLESS pozwala kompilować pliki LESS przy zapisie.
Sublime Text 2 Dzięki rozszerzeniom posiada zaawansowane wsparcie dla LESS: parsowanie plików przy zapisie, określanie miejsca docelowego dla plików LESS, pomijanie plików przy generowaniu plików CSS etc.
Espresso, Dreamweaver i inne Pozostałe edytory z reguły pozwalają co najmniej na dodanie wsparcia dla składni LESS.
Mój plugin - LESSer
Jak działa LESSer?
LESSer - beta Wersję beta można pobrać z: https://github.com/dziudek/lesser
Składnia LESS
Komentarze Wymarzona składnia // komentarz inline :-)
Zmienne @page-width: 1200px;.wrapper { max-width: @page-width;
Zmienne Osadzanie zmiennych w wartościach CSS: background-image: url("@{path_images/img.png");
Zmienne w CSS http://dev.w3.org/csswg/css-variables/
Zagnieżdżanie reguł
Zagnieżdżanie reguł.class1 { property: value;.class2 { property: value; &:hover { property: value; =>.class1 { property: value;.class1.class2 { property: value.class1.class2:hover { property: value;
Zagnieżdżanie reguł.class1 { &.big { property: value; =>.class1.big { property: value;
Zagnieżdżanie reguł.class1 { property: value;.class1 { property: value; @media (max-width: 580px) { property: value; => @media (max-width: 580px) {.class1 { property: value; Less nie grupuje reguł dla media queries!
Zagnieżdzanie reguł.child,.sibling {.parent & { color: black; & + & { color: red; =>.parent.child,.parent.sibling { color: black;.child +.child,.child +.sibling,.sibling +.child,.sibling +.sibling { color: red;
Parsowanie CSS w przeglądarkach Warto na to zwrócić uwagę gdy: Liczy się dla nas każda milisekunda Nasz kod CSS jest naprawdę złożony Gdy mamy problemy z wydajnością renderowania się strony (głównie urządzenia mobilne)
Parsowanie CSS w przeglądarkach Przeglądarki parsują selektory od prawej do lewej: #menu li a
Parsowanie CSS w przeglądarkach Selektor potomka jest najwolniejszym z selektorów #menu li a (trochę) lepiej jest użyć: #menu > li > a
Parsowanie CSS w przeglądarkach Klasyfikacja reguł według wydajności (malejąco): 1. reguły ID 2. reguły klas 3. reguły tagów 4. reguły uniwersalne Powyższa klasyfikacja jest uproszczona dla celów poglądowych - tak naprawdę najwolniejsze są pseudoklasy i selektory atrybutów, a dodatkowo pomiędzy ID a klasami z reguły nie ma zbyt wielkich różnic w wydajności.
Parsowanie CSS w przeglądarkach 1. https://developers.google.com/speed/docs/bestpractices/rendering?hl=pl 2. http://stackoverflow.com/questions/5797014/ why-do-browsers-match-css-selectors-fromright-to-left 3. http://csswizardry.com/2011/09/writing-efficientcss-selectors/
Operacje matematyczne @a: 20px; @b: (@a * 10); // 200px @c: (@a + @b); // 220px width: ((@c + 36) * 2px); // 512px color: #222 + #333; // #555
CSS i calc() width: calc(100% - 20px); font-size: calc(2 * 2em - 24px); LESS nie uwzględnia rodzaju użytych jednostek
Mixiny
Najprostszy mixin.border-radius { -webkit-border-radius: 5px; -moz-border-radius: 5px; border-radius: 5px; można też zastosować nazwę #border-radius
Podwójne właściwości Nawet jeżeli powtórzymy jakąś właściwość, to jeżeli w obu wypadkach ma ona taką samą wartość - nie zostanie ona powielona (pod warunkiem, że powielimy ją w obrębie jednej klasy/mixinu)
Ukrywanie mixinów Mixiny traktowane są jak klasy CSS chyba, że zrobimy z nich mixiny bezparametrowe:.shadows() { box-shadow: 0 0 3px #000; text-shadow: 0 0 3px #000; Są one wtedy ukrywane w wynikowym kodzie CSS
Mixiny - parametry.shadows(@size) { box-shadow: 0 0 @size #000; text-shadow: 0 0 @size #000; Użycie: nav.submenu { border: 1px solid #eee;.shadows(3px);
Mixiny - wartości domyślne.shadows(@size: 3px) { box-shadow: 0 0 @size #000; text-shadow: 0 0 @size #000; Użycie: nav.submenu { border: 1px solid #eee;.shadows;
Mixiny -!important Użycie!important po mixinie powoduje automatyczne dodanie!important do wszystkich właściwości w nim użytych.shadows(20px; #aaa)!important;
Guard mixins.mixin(@a) when (@a > 10).mixin(@a) when (@a > 10), (@a < 100) // OR.mixin(@a) when (@a > 10) and (@a < 100).mixin(@a) when not (@a > 10)
Selektory w mixinach W mixinach można umieszczać też całe grupy selektorów, co powoduje, że możemy generować fragmenty kodu zależnie od wartości zmiennych:.mixin() {.selector { property: value;
Mixiny - przestrzenie nazw #package {.mixin() {... Użycie:.cssclass { #package >.mixin;
Funkcje http://lesscss.org/#reference
Importowanie kodu LESS pozwala zarówno na importowanie plików *.css jak i *.less W wypadku plików *.css wszystkie deklaracje @import przenoszone są podczas kompilacji na samą górę pliku (ewentualnie są umieszczane zaraz po @charset)
Importowanie kodu Pliki *.less można importować wewnątrz reguł CSS:.class { @import test.less ; border: 10px solid #aaa;
Przerwa dla gardła ;-)
Level++
Przecinki a średniki Parametry można rozdzielać przecinkami lub średnikami, przy czym średniki są bezpieczniejsze:.shadows(@size: 3px; @color: #000) { box-shadow: 0 0 @size @color; text-shadow: 0 0 @size @color; Na końcu parametru z przecinkami można dodać średnik aby był traktowany jako jeden argument:.test(a, b, c;);
Drugi sposób na przecinki ~ text Ważne! samo text powoduje wstawienie wartości z cudzysłowami
Problemy z calc() calc(~ WYRAŻENIE ) zamiast calc(wyrażenie)
Takie same nazwy mixinów Możemy zdefiniować kilka mixinów o tej samej nazwie - użyte zostaną wszystkie mixiny, które mają odpowiednie argumenty.mixin(@a; @b: 10);.mixin(@a: 20; @b: 10);.mixin(@a:30; @b); W powyższym wypadku wywołanie:.mixin(10); spowoduje wykorzystanie kodu CSS z pierwszego i drugiego mixinu (i powielenie właściwości CSS!)
Złożone argumenty mixinów @arguments pozwala użyć wartości wszystkich parametrów za jednym zamachem:.shadows(@size: 3px; @color: #000) { box-shadow: 0 0 @arguments; text-shadow: 0 0 @arguments;
Mixiny - @rest LESS pozwala na określenie zmiennej ilości argumentów - tutaj przydaje się zmienna @rest:.shadows(@pos: 3px 4px; @rest...) { box-shadow: @pos @rest; text-shadow: @pos @rest; Można też sprawić, że pierwsza zmienna przyjmie dowolny ciąg argumentów:.test(@a...) {...
Mixiny - pattern matching Jako pierwszy argument mixina możemy podać ciąg znaków - wtedy będzie wymagał do swojego wywołania podania tego ciągu znaków jako pierwszego argumentu:.margins(mobile; @value: 20px).margins(tablet; @value: 30px).margins(@_;@value: 50px) Wtedy pierwszy mixin wywoła się gdy: @mode: mobile;.margins(@mode);.margins(@mode; 10px);
Kod JS w mixinach Kod JS jest wykonywany gdy użyjemy składni: `kod JS`.class { height: `document.body.clientheight`; (działa tylko z less.js)
Interpolacja selektorów @big-headers: ~"h1, h2, h3"; @small-headers: ~"h4, h5, h6"; @{big-headers { font-weight: 600; @{small-headers { font-weight: 400; @{big-headers, @{small-headers { text-transform: uppercase; => h1, h2, h3 { font-weight: 600; h4, h5, h6 { font-weight: 400; h1, h2, h3, h4, h5, h6 { text-transform: uppercase;
Zmienne nazwy zmiennych @color-frontpage: #aaa; @color-subpage: #bbb;.colorize(@page) { background-color: ~"@{color-@{page";.wrapper {.colorize(subpage);
Aliasy.transition-timing-function(@value) { -webkit-transition-timing-function: @value; -moz-transition-timing-function: @value; -o-transition-timing-function: @value; transition-timing-function: @value; // Alias.trans-timing(@value) {.transition-timing-function(@value);
Co dalej? LESS się ciągle rozwija - trzeba być na bieżąco ;-) Praktyka, praktyka i jeszcze raz... praktyka ;-) Analiza kodu LESS popularnych otwartych projektów SASS?
Źródła informacji 1. http://lesscss.org/ (EN) 2. http://ciembor.github.io/lesscss.org/ (PL) 3. https://github.com/cloudhead/less.js/wiki (EN) 4. Stack Overflow ;-)
Gratis ode mnie ;-) Mój standardowy zestaw mixinów: https://github.com/dziudek/less-mixins
Pytania?
Dziękuję za uwagę