Uwaga: wyszedł mi "odrobinkę" przydługi wstęp. Zabieganych zapraszam od razu do konkretów.
Nie da się ukryć że frontend developerzy (czy inaczej "ci od cięcia grafiki" :) łatwego życia nie mają. Pierwsza sprawa to niedoskonałości samych języków (CSS, xHTML, Javascript+DOM), druga to różnice i bugi (zwane inaczej ficzerami) w obsłudze przez przeglądarki. Każdy z tych języków na szczęście się rozwija (CSS3, HTML5, ECMAScript 5), a implementacja standardów jest, nawet w Internet Explorerze, sukcesywnie polepszana. Trwa to jednak strasznie długo, dlatego warto pokombinować samemu.
Ostatnio opisałem plugin do edytorów tekstów dzięki któremu można przyspieszyć pisanie HTMLa. Dzisiaj pod lupę chciałbym wziąć CSS. Osobiście na tempo pisania listy właściwości nie narzekam - mam własny zestaw snippetów, który umila mi życie. Inaczej ma się sprawa w stosunku do selektorów. Już w niedużym projekcie potrafią się zrobić cuda typu:
#content .news_list .item .title {...} #content .news_list .item .date {...} #content .news_list .item .date .day {...}
Albo:
.s1 { width:120px; float:left; font-size:1.1em; margin-left:10px; color:#FA0; } /*gdzieś kawałek dalej:*/ .s2 { width:120px; float:left; font-size:1.1em; margin-left:10px; color:#C14; }
Gdzie wypada to połączyć do pary selektorów i dla każdego z osobna jeszcze kolor ustawić. Niestety to najprostszy przypadek z tej rodziny, czasami trzeba znaleźć części wspólne dla kilku reguł po kilkunaście właściwości, albo olać wszystko.
Dalej można wymieniać:
co to był za kod tego pomarańczowego, który używam do podkreśleń?
-moz-border-radius: 5px; -webkit-border-radius: 5px; border-radius: 5px;
Co więcej - to są problemy które pojawiają się już na etapie stron o średniej wielkości i kodowania w pojedynkę. W przypadku sporych serwisów (długo i wieloetapowo rozwijanych) i większego zespołu potrafią urosnąć do &*$#$%. To jest jak rzeźba w gównie. Trzeba przepisać cały ten bajzel
. Sam ostatnio tak opisałem jeden commit do bazy.
Jakiś czas temu dostałem od kogoś link do LESS CSS - parsera/kompilatora (nie wiem jak to nazwać) rozszerzającego możliwości CSSa o kilka interesujących rzeczy typu: zmienne, obliczenia, reguły zagnieżdżone, itd. O temacie jednak zapomniałem (mało ostatnio koduję) i przypomniał mi kilka dni temu o nim Occulkot, który podrzucił mi Sassa. Obydwa kompilatory napisane są w Rubym. Zrobiłem mały research i znalazłem jeszcze podobne cudo, tyle że w Pythonie - Clever CSS.
Po krótkim wczytywaniu się w przykłady zdecydowałem się na LESSa. Dodaje do CSSa trochę mniej ficzerów, ale przynajmniej nie zmienia jego składni (plik CSS jest poprawnym plikiem LESS) i nie wymusza na mnie jedynego, właściwego formatowania kodu (Sass i Clever CSS mają składnię czerpiącą z języków w jakich zostały napisane - odpowiednio Ruby i Python - wymagają więc wcięć).
Polecam przeczytać Haml-sass, czyli tragedia w dwóch aktach. Przy okazji tej lektury ja również odradzam Hamla, który jest w teorii cudownym (zen i te sprawy) systemem szablonów HTMLa. Tylko, że kompletnie to nieczytelne, brzydkie i bez sensu.
Po tym przydługim wstępie (chciałem usunąć, ale żal jak się już napisało) przejdźmy do konkretów.
Instalacja, dla posiadających gema (ci nieposiadający najlepiej niech go zainstalują), jest banalna:
$ sudo gem install less
Ewentualnie jeśli ktoś koduje w Railsach, to może go zainteresować ten plugin.Najprostszym sposobem skorzystania z LESSa jest jednak przy pomocy konsoli:
$ lessc style.less
Wykonanie tego polecenia spowoduje utworzenie pliku style.css zawierającego wynik działania kompilatora.
Kompilując taki kod:
@brand_color: #4D926F; #header { color: @brand_color; } h2 { color: @brand_color; }
Otrzymamy:
#header, h2 { color: #4d926f; }
Jak widać, poza podstawieniem zmiennej, LESS połączył też reguły o tej samej liście właściwości. To informacja dla miłośników oszczędzania na bajtach transferu :).
CSSowe DRY :).
.rounded_corners (@radius: 5px) { -moz-border-radius: @radius; -webkit-border-radius: @radius; border-radius: @radius; } h1 .stronger { font-weight:bold; font-size:1.1em; } #header { .rounded_corners; h1 .stronger; } #footer { .rounded_corners(10px); }
Po kompilacji:
h1 .stronger { font-weight: bold; font-size: 1.1em; } #header { -moz-border-radius: 5px; -webkit-border-radius: 5px; border-radius: 5px; font-weight: bold; font-size: 1.1em; } #footer { -moz-border-radius: 10px; -webkit-border-radius: 10px; border-radius: 10px; }
Przy czym definicja reguły musi wystąpić przed jej użyciem. Przykład z wykorzystaniem h1 .stronger nie ma uzasadnienia w praktyce (jest w zasadzie błędny), ale chciałem tylko pokazać, że można wykorzystywać ponownie dowolne reguły.
To chyba mój ulubieniec. Dzięki temu rozszerzeniu unikniemy pisania co chwilę mega długich selektorów. Dziwię się w ogóle, że nie ma tego w oficjalnym CSSie.
#header { color: red; a { font-weight: bold; text-decoration: none; } > p { color: blue; } }
Po kompilacji:
#header { color: red; } #header a { font-weight: bold; text-decoration: none; } #header > p { color: blue; }
Chyba nie muszę tłumaczyć.
@the-border: 1px; @base-color: #111; #header { color: @base-color * 3; border-left: @the-border; border-right: @the-border * 2; } #footer { color: (@base-color + #111) * 2; }
Po kompilacji:
#header { color: #333333; border-left: 1px; border-right: 2px; } #footer { color: #444444; }
To by było na tyle. Jeśli kogoś temat zainteresował to zapraszam do specyfikacji, gdzie autor omawia jeszcze kilka dodatków.
W każdym razie - cztery małe ficzery, a jak cieszą, prawda? :)
Zastanawiałem się tylko jak usprawnić kompilację po wprowadzeniu zmian do pliku LESS. Najfajniej gdyby udało mi się w moim VIMie podłączyć wykonanie $ lessc pod operację zapisania, ale to nie na moje umiejętności. Mcv zaproponował mi takiego Makefile'a:
%.css: %.less lessc $<
Wykonujemy go uruchamiając: $ make plik1.css plik2.css. To już powinno mi się udać podpiąć w VIMie pod zapis pliku. Ewentualnie można spróbować tak:
all: *.css %.css: %.less lessc $<
Co zadziała automatycznie dla wszystkich istniejących już plików CSS po wykonaniu prostego $ make. Przy czym, jeśli się mylę, to proszę mnie poprawić, bo nigdy żadnego makefile'a sam nie napisałem.
EDIT: w komentarzach pojawiły się rozwiązania mojego problemu.
Snippety do htmla? Nieeee. Zobaczcie Zen Coding. W skrócie działa to tak. Wpisuję w edytorze CSSową składnią:
div#content>h1+p
Wciskam jakąś kombinację klawiszy i dostaję:
<div id="content"> <h1></h1> <p></p> </div>
Sprytne, nie? :) Ale to jeszcze mało. Spróbujcie tego:
div#top>h1>a[title=Do strony głównej]{Moja strona}<ul#menu>li.pos$*3>a
<div id="top"> <h1> <a href="" title="Do strony głównej">Moja strona</a> </h1> <ul id="menu"> <li class="pos1"> <a href=""></a> </li> <li class="pos2"> <a href=""></a> </li> <li class="pos3"> <a href=""></a> </li> </ul> </div>
Chyba nie muszę mówić jak bardzo taka pomoc przyspiesza pracę. Napisanie z palca kodu z drugiego przykładu zajęłoby mi przypuszczalnie więcej niż 2 minuty. Gdybym użył snippetów (do których przy HTMLu nie mogę się przyzwyczaić) może skróciłbym ten czas dwukrotnie. Zaś używając wynalazku Zen Coding całość naklepałem w 20s (i to nie mając wprawy). Tak więc gorąco polecam.
Gdyby ktoś szukał wtyczki do VIMa, to powstał plugin, którego twórca zainspirował się Zen Codingiem.