Banalną składnię CSS-a można rozszerzyć. Zobacz jak dodać do niego zmienne i jakie frameworki przyśpieszą pracę.
„O ile łatwiejszy byłby CSS, gdyby wyposażyć go w zmienne, szablony i biblioteki, dzięki którym nie musiałbym za każdym razem pisać wszystkiego od zera” – powiedział niedawno znajomy programista, który musiał zająć się zakodowaniem arkusza stylów. Nie jest jedynym, który wpadł na taki pomysł. Niektórzy nawet zaimplementowali gotowe rozwiązania jego problemów.
Czego brakuje CSS-owi?
CSS nie posiada zmiennych takich jak w innych językach. Nie możemy na początku arkusza zdefiniować kodu typu:
kolorPomocniczy = #f00;
kolorTrzeci = #eee;
aby w dalszej części używać nazw, a w razie potrzeby zmieniać tylko pojedynczych wartości. Za każdym razem kiedy chcemy zmienić kolor z #666 na #555 musimy przeszukiwać cały dokument. Jeśli zmieniamy kolor za pomocą edytora nie jest to problemem, ale co, jeśli zmiany mają być generowane przez skrypt? Zmienne byłyby bardzo użyteczne.
Jeśli mielibyśmy zmienne, to dlaczego nie pójść dalej i nie stworzyć funkcji zwracających kod na podstawie podanych argumentów? Albo wyrażeń arytmetycznych pozwalających na ustalenie marginesu akapitu jako 1,5 wysokości zdefiniowanego jako zmienna marginesu podstawowego? Takie efekty można uzyskać korzystając z preprocesorów kodu CSS takich jak:
- LESS CSS (http://lesscss.org/ ),
- Switch CSS (http://sourceforge.net/projects/switchcss/ ),
- Turbine (http://turbine.peterkroener.de/index.php )
- DT CSS (http://code.google.com/p/dtcss/),
- Sass (http://sass-lang.com/ ).
Preprocesory CSS
Preprocesory CSS działają na podobnej zasadzie. Analizują arkusz stylów zapisany w pliku własnego typu w poszukiwaniu rozszerzonych konstrukcji takich jak np. zmienne albo wyrażenia arytmetyczne i generują na ich podstawie poprawny plik CSS. Ma to ułatwić tworzenie i utrzymanie kodu oraz wprowadzenie zmian. Możliwości i składnia preprocesorów są podobne. Różnią się głównie wymaganiami systemowymi (np. modułem do Apache’a lub interpreterem języka skryptowego) i oczywiście implementacją.
Przyjrzyjmy się działaniu preprocesora na podstawie LESS CSS. Ma on kilka wersji napisanych m.in. w PHP, .NET i… JavaScriptcie. Ta ostatnia wersja oczywiście nie nadaje się do kodu produkcyjnego, gdyż przy każdym otwarciu strony wymaga przekształcenia kodu z wersji LESS na CSS, ale sprawdzi się do przetestowania możliwości preprocesora. Aby go uruchomić wystarczy dodać w sekcji head strony kod:
W arkuszu możemy już używać dodatkowych opcji, o ile zmienimy jego rozszerzenie na .less i zalinkujemy:
Zmienne z LESS CSS
Zmienne definiujemy tak jak w językach programowania:
@moj_kolor: #222;
Następnie możemy ich używać w kodzie:
h1 {color: @moj_kolor }; //h1 {color: #222 };
Na zmiennych możemy przeprowadzać wyrażenia arytmetyczne.
h2 {color: @moj_kolor * 2 }; //h2 {color: #444 };
Jeśli zmienne to za mało, w ten sam sposób możemy skorzystać z klas mieszanych (mixins). Definiujemy całą klasę wraz z domyślną wartością argumentu:
.zaokrąglone_rogi (@promien: 5px) {
-moz-border-radius: @promien;
-webkit-border-radius: @promien;
border-radius: @promien;
}
Za każdym razem kiedy w arkuszu pojawi się kod {html}.zaokrąglone_rogi;{/html} preprocesor przekształci go na kod:
-moz-border-radius: 5px;
-webkit-border-radius: 5px;
border-radius: 5px;
Argument domyślny możemy zmienić za pomocą kodu {html}.zaokrąglone_rogi (@promien: wartość);{/html}. Zmienne @promien zostaną zastąpione wartością podanego argumentu.
Zagnieżdżenia kodu
Możemy również zmienić strukturę arkusza, żeby odpowiadała logicznej strukturze serwisu. Zamiast pisać:
#header {
color: red
}
#header a {
font-weight: bold;
text-decoration: none;
}
Możemy użyć łatwiejszej do uporządkowania konstrukcji:
#header {
color: red;
a {
font-weight: bold;
text-decoration: none;
}
}
Ponadto taki zapis pozwala stosować zmienne lokalne (rozpatrywane tylko w zasięgu klamerek) i globalne. Style mogą być wielokrotnie zagnieżdżone. Więcej przykładów znajduje się w dokumentacji ({html}http://lesscss.org/docs{/html}).
Frameworki CSS
Kolejną po braku zmiennych niedogodnością CSS-a jest nieobecność frameworków znanych z języków programowania. Ruby ma swoje Rails, JavaScript – jQuery, a PHP – Zend. Okazuje się jednak, że również koderzy CSS-a stworzyli własne {link_wew 4689}frameworki{/link_wew}, w dodatku jest ich całkiem sporo jak na tak prosty język jak CSS.
- Blueprint (http://www.blueprintcss.org/), któremu poświęciliśmy {link_wew 3518}cały artykuł{/link_wew},
- 960 Grid System (http://960.gs ) – framework ułatwiający pracę na siatce
- Elements (http://elements.projectdesigns.org/ ) – lekki framework zawierajacy m.in. reset stylów
- BlueTrip (http://bluetrip.org ) – połączenie Blueprint, 960.gs oraz Elements w jednym pliku
- YAML (http://www.yaml.de/en/home.html) – skomplikowany framework wymagający wiele nauki
- YUI 2: Grids CSS (http://developer.yahoo.com/yui/grids/ ) – ważący 4kb framework pozwalający na budowę 1000 różnych układów strony
- OOCSS (https://github.com/stubbornella/oocss/wiki ) – obiektowy CSS (mamy nadzieję, że to tylko żart autorki!)
Frameworki CSS mogą być przydatne do szybkiego złożenia szablonu strony, gdyż dostarczają klasy do najczęściej stosowanych elementów takich jak układ dwukolumnowy, stopka na szerokość całej strony czy lightbox. Niestety większość pobranego kodu będzie nigdy nieużywana, a wprowadzenie zmian wymusza zagłębianie się w zoptymalizowany pod względem rozmiaru a nie czytelności kod, co nie jest ani proste, ani przyjemne.
Innym wyjściem może być skorzystanie tylko z fragmentów frameworka, np. pliku ujednolicającego typografię z Blueprint ({html}http://www.blueprintcss.org/blueprint/src/typography.css {/html}).
A może wystarczy reset stylów?
Prawie wszystkie frameworki CSS wyposażone są ponadto w tzw. reset stylów. Przeglądarki różnią się domyślnymi stylami (marginesami, ramkami, rozmiarami i wagą fontu oraz złamaniem linii) przypisanymi niektórym elementom. Np. w IE8 i Firefoksie domyślny margines formularza (form) ma wartość „0”, w Operze i Safari „0 0 1em”, a w IE7 „14.25pt 0”. Inne różnice przedstawia tabela http://lists.w3.org/Archives/Public/www-style/2008Jul/att-0124/defaultstyles.htm.
Żeby strona wyglądała tak samo pod wszystkimi przeglądarkami można zacząć arkusz od ustawień ujednolicających indywidualne wartości atrybutów różnych przeglądarek. To tzw. reset stylów. Można go dokonać „masowo” za pomocą wpisu {html}*{margin:0;padding:0;border:0 none;font-size:100%;line-height:1;font-weight:400;}{/html} albo bardziej złożonych arkuszy uwzględniających wyłącznie zmieniane elementy. Popularne zestawy reguł resetujących style:
- Reset Erica Meyera (http://meyerweb.com/eric/tools/css/reset/ ),
- reset Yahoo (http://developer.yahoo.com/yui/reset/#code ),
- reset uwzględniający nowe elementy HTML5 (http://html5doctor.com/html-5-reset-stylesheet/ ).
Niestety reset ma wady: wyzerowane wartości trzeba ponownie ustawić dla każdego elementu (przez co rozmiar pliku rośnie) a zastosowanie selektora uniwersalnego może wprowadzić nieoczekiwane konsekwencje (np. wyzeruje również pseudoklasę :focus) i powodować opóźnienia ze względu na złożoność obliczeniową wyrednerowania takiej strony.
Do resetowania stylów, frameworków i preprocesorów należy więc podejść ostrożnie, ale warto mieć świadomość istnienia różnic w działaniu przeglądarek i sposobów ich naprawy, możliwości dodania zmiennych czy faktu, że ktoś już napisał kod do takiego szablonu jakiego potrzebujemy.