
CSS, czyli kaskadowe arkusze stylów, Cascading Style Sheets) to język programowania, który służy do opisu formy prezentacji stron www. Został stworzony głównie po to, aby odseparować strukturę dokumentu, wyrażoną w HTML-u od formy jego prezentacji, co ułatwia zarządzanie projektem. W skrócie, CSS można to jako zbiór reguł opisujących, jak dany element powinien wyglądać, HTML - z czego się składać, a JavaScript - jak się zachowywać. Jakie wady ma CSS, jakie nawyki utrudniają pracę z nim i jak zapanować nad nimi tak, by praca w w dużych komercyjnych projektach była łatwiejsza pisze specjalnie dla interaktywnie.com Tomasz Plewka, Frontend Web Developer z SYZYGY Warsaw.
CSS, czyli kaskadowe arkusze stylów, Cascading Style Sheets) to język programowania, który służy do opisu formy prezentacji stron www. Został stworzony głównie po to, aby odseparować strukturę dokumentu, wyrażoną w HTML-u od formy jego prezentacji, co ułatwia zarządzanie projektem. W skrócie, CSS można to jako zbiór reguł opisujących, jak dany element powinien wyglądać, HTML - z czego się składać, a JavaScript - jak się zachowywać. Jakie wady ma CSS, jakie nawyki utrudniają pracę z nim i jak zapanować nad nimi tak, by praca w w dużych komercyjnych projektach była łatwiejsza pisze specjalnie dla interaktywnie.com Tomasz Plewka, Frontend Web Developer z SYZYGY Warsaw.
BEMIT, czyli o połączeniu skalowalnej architektury ITCSS oraz konwencji BEM
Czy kiedykolwiek dołączyłeś do projektu, gdzie jakakolwiek próba przebrnięcia przez gąszcz reguł CSS’a kończyła się u Ciebie bólem głowy? A może brak uporządkowania i stopień powiązania reguł CSS’a i „contentu” zdefiniowanego w HTML’u powodował, że (tak jak pewnie wielu innych przed Tobą) dopisałeś kilka reguł korygujących wygląd tego przycisku na samym końcu arkusza z odpowiednio wysoką specyficznością (ang. specificity) selektora? A może byłeś częścią zespołu front-endowego, pracującego nad początkowo niewielkim projektem, który z biegiem czasu stał się pełnoprawnym produktem o ogromnej skali i zasięgu? Czy pamiętasz, jak przyjemnie pisało się te reguły w arkuszu, nie myśląc zupełnie o możliwym rozwoju projektu? Czy żałujesz teraz, że jako Lead/Senior Developer nie poświęciłeś czasu na odpowiednie przemyślenie architektury CSS’a i sposobu jego pisania?
Jestem przekonany, że absolutna większość początkujących developerów miała styczność z podobnymi sytuacjami w mniejszym lub większym stopniu. Sam się z tym mierzyłem pracując nad warstwą front-endową w projektach opartych na WordPress’ie. Odczuwałem wówczas autentyczny strach, patrząc na ogrom reguł w pojedynczym arkuszu `styles.css` [sic!] i zamiast zwrócić czyjąś uwagę na ten problem, sam „dorzucałem swoje 3 grosze” pisząc kolejne reguły na końcu arkusza.
Jeśli którykolwiek z powyższych tematów jest bliski Twojemu deweloperskiemu sercu, mam dla Ciebie garść przydatnych informacji. Przybliżę nie tylko pojęciowe ujęcie architektury CSS-a, ale pokrótce przedstawię propozycję ciekawej i skalowalnej architektury opartej o ITCSS oraz BEM (BEMIT), wspomnę o najczęściej popełnianych błędach podczas pracy z CSS-em oraz udzielę kilku rad jak wspomnianych pułapek uniknąć. Zapraszam do lektury!
Kilka słów o CSS-ie i jego wadach
To powszechne przeświadczenie, że o tym jak dobrym deweloperem jesteś, świadczy fakt szybkiego i sprawnego „zakodowania” projektu graficznego w zintegrowanym środowisku programistycznym (ang. IDE). O ile jest to niewątpliwie istotny wyznacznik umiejętności Front-End Developera, to tak naprawdę zaniedbywane są aspekty, których brak przy pisaniu kodu w innych językach byłby niedopuszczalny. Czy Twój kod jest czytelny? Czy podlega łatwej modyfikacji? Czy jest skalowalny? Te i wiele innych podobnych pytań jest jak najbardziej zasadnych również w stosunku do CSS-a, którego zaniedbanie w początkowych fazach pracy nad projektem/produktem może doprowadzić do wielu zmarnowanych godzin podczas prób debuggowania, refactoringu, a w skrajnych przypadkach może nawet opóźnić wdrożenie produkcyjne.
CSS wymyślono po to, by w łatwy i szybki sposób zdefiniować wizualną warstwę aplikacji czy produktu poprzez pisanie reguł składających się z własności (np. background-color) oraz odpowiadających im wartości (np. blue). Brzmi przyjemnie. O ile cechy CSS-a, takie jak kaskadowość, specyficzność selektorów czy dziedziczenie w mniejszych projektach mogą przejść niezauważone, to podczas pracy nad dużym, komercyjnym produktem źle zaprojektowany CSS może dać się niemiłosiernie we znaki nawet najbardziej doświadczonym developerom.
Nie pomaga również fakt, że CSS jest deklaratywny. Tworzone reguły żyją w globalnej przestrzeni nazw, co prowadzi do kolizji nazw klas. Jednak zrzucanie całej winy na CSS byłoby niesprawiedliwe i zdecydowanie na wyrost, bowiem my, developerzy, powinniśmy wziąć na siebie większą odpowiedzialność przy tworzeniu struktury arkuszy CSS-a. Bardzo często zdarza się, że w projekcie CSS brakuje dokumentacji (Kto o tym myśli? Kto ma na to czas?), a developerzy nie mają odpowiedniej wiedzy na temat samego projektu i jego istniejącej struktury. Nierzadko w zespołach developerskich spotykają się ludzie o różnym poziomie umiejętności, stylu pracy, co może przekładać się na to, że pisany kod jest chaotyczny i zdezorganizowany. Rodzi się pytanie: czy i jak możemy temu zapobiec? Jednak zanim zaadresujemy to pytanie, stwórzmy listę najczęściej popełnianych błędów i złych praktyk spotykanych przy pisaniu CSS’a.
Trudno się pozbyć starych nawyków
Celem każdego developera zajmującego się tworzeniem warstwy wizualnej w CSS-ie powinno być dążenie do tego, by pisany kod był:
- przewidywalny (ang. predictable) – dodanie czy zaktualizowanie reguły w arkuszu CSS powoduje przewidywalne (zgodne z intencjami modyfikującego kod) zmiany wizualne w aplikacji;
- reużywalny (ang. reusable) – reguły CSS-a tworzone są w sposób niezależny od siebie oraz nie są ściśle powiązane z warstwą „contentową” HTML-a, przez co tworzenie nowych komponentów odbywa się w oparciu o mniejsze/składowe elementy;
- łatwy w utrzymaniu (ang. maintainable) – dodanie nowego komponentu czy rozszerzenie jego funkcjonalności nie powinno wymagać edycji istniejącego już kodu w myśl zasady SOLID (zasada otwarte – zamknięte);
- skalowalny (ang. scalable) – reguły i sposób pisania kodu CSS nie powinien być czynnikiem hamującym możliwy rozwój aplikacji/produktu, a samo dołączenie do zespołu projektowego nie powinno wiązać się z tygodniami spędzonymi nad rozszyfrowywaniem kodu zawartego w arkuszach.
Jednym z kluczowych czynników mających na celu dążenie do perfekcji w pisaniu reguł CSS-a jest wyzbycie się starych, nierzadko złych praktyk nabytych na różnych etapach kariery developerskiej. Poniżej przedstawiam najważniejsze „grzechy główne” w procesie tworzenia CSS-a:
Modyfikowanie komponentu w zależności od kontekstu (strukturalnego „rodzica”)
Wyobraź sobie sytuację, w której zaprojektowałeś komponent pojawiający się na większości podstron w tworzonej przez Ciebie aplikacji (np. button, sidebar). Nierzadko zdarza się, że wygląd tego komponentu jest spójny na wszystkich podstronach z wyjątkiem tego jednego, jedynego miejsca w aplikacji. W tym przypadku możesz pokusić się o napisanie czegoś takiego:
.sidebar {
background: rgba(0, 0, 0, 0.5);
border: 1px solid black;
color: black;
width: 33%;
}
#aside .sidebar {
width: 250px;
}
body.contact-page .sidebar {
background: white;
}
Co jest nie tak z powyższym kodem? Z pozoru nic. Jednak mając na uwadze cel, do którego dążymy, to przytoczony właśnie przykład:
- jest nieprzewidywalny – zmiana reguł głównego komponentu nie powoduje, że wygląda on spójnie na wszystkich podstronach ze względu na zależność od kontekstu;
- nie jest skalowalny/reużywalny – w przypadku, gdy klient zażyczy sobie dodania sidebar’a z podstrony kontaktu do innej podstrony, trzeba będzie dopisać nowe reguły CSS-a;
- nie jest łatwy w utrzymaniu – dzieje się tak dlatego, że każda zmiana projektu graficznego komponentu sidebar, wymaga zmiany w kilku miejscach w arkuszu CSS.
Star Specificity Wars
.title { … }
…
#homepage .title { … }
…
#main .title { … }
…
#contact-page #aside .title { … }
…
#content .title {
color: gray !important;
}
Pomimo uporządkowania i nadania struktury arkuszom CSS, używania konwencji nazewnictwa klas (ang. naming convention, np. BEM), specyficzność CSS-a oraz flaga `!important` mogą zrujnować całą ciężką pracę i wysiłek włożony w projekt. Można to przedstawić na wykresie zależności specyficzności od pozycji danej reguły w arkuszu CSS (rys. 1.).
Rys. 1. Wykres zależności specyficzności od pozycji reguły CSS-a w arkuszu. Obszary o wysokiej specyficzności. Źródło: speakerdeck.com.
Fakt występowania rejonów o wysokiej specyficzności nie jest zły sam w sobie. Problem pojawia się, gdy developer pracuje w obszarze o niskiej specyficzności (rys. 2.). Wówczas taki developer musi niejako wygrać batalie specyficzności (ang. specificity wars), która polega na stworzeniu selektora o wyższej specyficzności (nadpisaniu poprzedniego selektora). Idąc tym tropem można sobie wyobrazić, do czego może to doprowadzić.
Rys. 2. Wykres zależności specyficzności od pozycji reguły CSS-a w arkuszu. Obszary o niskiej specyficzności. Źródło: speakerdeck.com.
Ścisłe powiązanie warstwy „contentowej” (HTML) i wizualnej (CSS)
Spójrzmy na kilka przykładowych linijek kodu:
#navbar ul li ul li div { }
#main article h1:first-child { }
#aside > div > h3 + p { }
Co o tym sądzisz? Na pierwszy rzut oka wszystkie powyższe przykłady mają sens. Jednak pomyśl, co stałoby się, gdyby warstwa „contentowa” w HTML-u miała ulec nawet drobnej zmianie. Nagle okazuje się, że dany selektor jest totalnie bezużyteczny. Ścisłe powiązanie struktury pisanej w HTML-u oraz reguł CSS-a powoduje, że kod nie jest reużywalny i bardzo często nieprzewidywalny. W ten sposób tworzony arkusz CSS-a nie ma szans być skalowalny, ponieważ przedstawione powyżej reguły mają zastosowanie tylko wtedy, gdy struktura jest stała i nie zmienia się z czasem życia aplikacji.
Używanie ogólnych nazw klas
Zdarzyło Ci się pewnie używać w swoim projekcie klas typu `.title` czy `.content`, prawda? Popatrz na następujące fragmenty kodu:
HTML:
<div class="hero">
<h3 class="title">Title in hero</h3>
<h5 class="subtitle">Subtitle in hero </h5>
<div class="content">
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
In condimentum justo et est dapibus sit amet euismod ligula ornare.
Vivamus elementum accumsan dignissim.
</div>
</div>
…
<div class="sidebar">
<h3 class="title">Title in sidebar</h3>
<div class="content">
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
In condimentum justo et est dapibus sit amet euismod ligula ornare.
Vivamus elementum accumsan dignissim.
</div>
</div>
CSS:
.title {}
.subtitle {}
.content {}
…
.hero {}
.hero .title {}
.hero .subtitle {}
.hero .content {}
…
.sidebar {}
.sidebar .title {}
.sidebar .content {}
Im większy jest projekt, nad którym pracujesz, tym rośnie prawdopodobieństwo, że klasy typu `.title` czy `.content` pojawią się jeszcze w wielu innych miejscach. Niestety powyższy kod nie jest w żaden sposób przewidywalny i łatwy w utrzymaniu, ponieważ jakakolwiek zmiana stylu głównej klasy np. `.title` spowoduje, że ten sam tytuł umieszczony w komponencie `hero` będzie miał zupełnie inny wygląd - co może nie być tym, czego oczekiwałeś.
Reguła CSS-a ma wiele odpowiedzialności
Ta zła praktyka dotyczy głównie tworzenia klas w CSS-ie zawierających zarówno reguły wizualne (np. kolor tła czy czcionki), jak i te dotyczące struktury/pozycjonowania danego elementu (np. odstępy). Prowadzi to do tego, że ponowne użycie komponentu nieznacznie różniącego się od pierwowzoru (z tak skonstruowaną klasą) wiąże się ze zwykłym kopiowaniem i ponownym wklejaniem reguł CSS-a z niewielką zmianą zależną od występującego w danym miejscu kontekstu strukturalnego. Najłatwiej byłoby wykonać `refactoring` tej klasy i rozdzielić ją na reguły odnoszące się stricte do warstwy wizualnej oraz pozostałe odpowiadające jej strukturalnemu umiejscowieniu na stronie. Jednak w praktyce niewielu deweloperów (szczególnie tych mniej doświadczonych) się na to decyduje.
W kolejnym tekście pokażę, jak sprawić, by praca z CSS-em w dużych, komercyjnych projektach była przyjemniejsza!
Źródła:
- https://cheesecakelabs.com/blog/css-architecture-first-steps/
- https://philipwalton.com/articles/css-architecture/
- https://www.xfive.co/blog/itcss-scalable-maintainable-css-architecture/
- https://csswizardry.com/2015/08/bemit-taking-the-bem-naming-convention-a-step-further/
- https://www.creativebloq.com/web-design/manage-large-css-projects-itcss-101517528
Grafiki
- https://other.media/itcss-the-inverted-triangle-css-the-right-way-up/
- https://speakerdeck.com/dafed/managing-css-projects-with-itcss
Specificity graph
- https://jonassebastianohlsson.com/specificity-graph/
Pobierz ebook "Ranking Agencji Marketingowych 2025 roku i ebook z poradami o promocji w sieci"
Zaloguj się, a jeśli nie masz jeszcze konta w Interaktywnie.com - możesz się zarejestrować albo zalogować przez Facebooka.
Pomagamy markom odnosić sukces w Internecie. Specjalizujemy się w pozycjonowaniu stron, performance marketingu, social …
Zobacz profil w katalogu firm
»
Projektujemy i wdrażamy strony internetowe - m.in. sklepy, landing page, firmowe. Świadczymy usługi związane …
Zobacz profil w katalogu firm
»
Skorzystaj z kodu rabatowego redakcji Interaktywnie.com i zarejestruj taniej w Nazwa.pl swoją domenę. Aby …
Zobacz profil w katalogu firm
»
Interaktywnie.com jako partner Cyber_Folks, jednego z wiodących dostawców rozwiań hostingowych w Polsce może zaoferować …
Zobacz profil w katalogu firm
»
Pozycjonujemy się jako alternatywa dla agencji sieciowych, oferując konkurencyjną jakość, niższe koszty i większą …
Zobacz profil w katalogu firm
»
W 1999 roku stworzyliśmy jedną z pierwszych firm hostingowych w Polsce. Od tego czasu …
Zobacz profil w katalogu firm
»