Tomasz Dziuda “LESS – CSS dla leniwych”
Transkrypt
Tomasz Dziuda “LESS – CSS dla leniwych”
LESS - CSS dla leniwych Tomasz Dziuda Główny programista w GavickPro [email protected] 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 ;-) Analiza kodu LESS popularnych otwartych projektów Praktyka, praktyka i jeszcze raz... praktyka ;-) 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ę