Odkrywanie SMACSS: skalowalnej i modułowej architektury dla CSS
Opublikowany: 2022-03-11Kiedy pracujemy nad dużymi projektami lub z grupami programistów, często okazuje się, że nasz kod jest niechlujny, trudny do odczytania i trudny do rozszerzenia. Jest to szczególnie prawdziwe po upływie czasu, kiedy wracamy i patrzymy na to ponownie — musimy starać się zachować ten sam sposób myślenia, w jakim byliśmy, kiedy to pisaliśmy.
Tak więc wiele osób stworzyło architektury CSS, aby pomóc w stylizacji kodu tak, aby CSS stał się bardziej czytelny. SMACSS — czyli Scalable and Modular Architecture for CSS — ma na celu właśnie to zrobić. Jest to szczególny zestaw wytycznych dotyczących architektury CSS od Jonathana Snooka, który zaadoptowałem.
Teraz podejście architektoniczne SMACSS różni się nieco od frameworka CSS, takiego jak Bootstrap czy Foundation. Zamiast tego jest to zestaw zasad, bardziej przypominający szablon lub przewodnik. Zagłębmy się więc w niektóre wzorce projektowe CSS, aby dowiedzieć się, jak możemy ich użyć, aby nasz kod był lepszy, czystszy, łatwiejszy do odczytania i bardziej modułowy.
Każda struktura projektu SMACSS wykorzystuje pięć kategorii:
- Baza
- Układ
- Moduły
- Stan
- Temat
Baza
W SMACSS style podstawowe określają, jak element powinien wyglądać w dowolnym miejscu na stronie. Są to wartości domyślne. Jeśli używasz zresetowanego arkusza stylów, zapewnia to, że otrzymane style są takie same we wszystkich przeglądarkach, pomimo różnic między ich wewnętrznymi, zakodowanymi na stałe domyślnymi ustawieniami CSS.
W stylu podstawowym powinieneś uwzględniać tylko selektory gołe elementy lub te z pseudoklasami, ale nie z selektorami klasy lub identyfikatora. (Powinieneś mieć naprawdę dobry powód, aby umieścić w nim klasę lub identyfikator, być może tylko wtedy, gdy stylizujesz elementy wtyczki innej firmy i musisz zastąpić domyślną stylizację dla tego konkretnego elementu.)
Oto przykład, jak powinna wyglądać podstawowa jednostka plików:
html { margin: 0; font-family: sans-serif; } a { color: #000; } button { color: #ababab; border: 1px solid #f2f2f2; }
Powinien więc zawierać domyślne rozmiary, marginesy, kolory, obramowania i wszelkie inne domyślne wartości, które planujesz używać w swojej witrynie. Twoja typografia i elementy formularza powinny mieć ujednolicone style, które pojawiają się na każdej stronie i dają wrażenie, że są częścią tego samego projektu i motywu.
SMACSS czy nie, bardzo polecam unikanie używania !important
tak bardzo, jak to możliwe i nie używaj głębokiego zagnieżdżania, ale powiem o tym więcej w dalszej części tego postu. Również jeśli twoja praktyka polega na używaniu resetowania CSS, to jest to miejsce, w którym powinieneś to uwzględnić. (Wolę używać Sassa, więc umieszczam go na górze pliku, zamiast kopiować go lub odwoływać się do niego oddzielnie od elementu <head>
na każdej stronie.)
Układ
Style układu podzielą stronę na główne sekcje — nie na sekcje, takie jak nawigacja lub może na przykład akordeon, ale naprawdę podziały najwyższego poziomu:
Te układy będą zawierać wiele modułów CSS, takich jak pudełka, karty, nieuporządkowane listy, galerie i tym podobne, ale omówię więcej o modułach w następnej sekcji. Rozważmy przykładową stronę internetową, aby zobaczyć, co możemy podzielić na układy:
Tutaj mamy nagłówek, główny i stopkę. Te układy zawierają moduły, takie jak linki i logo w nagłówku u góry, pola i artykuły na stronie głównej oraz linki i prawa autorskie do stopki. Układom zwykle dajemy selektor identyfikatora, ponieważ nie powtarzają się one na stronie i są unikalne.
Powinieneś również poprzedzić reguły stylów układu literą l
, aby odróżnić je od stylów modułów. Zwykle tutaj stylizujesz elementy charakterystyczne dla układu, takie jak obramowanie, wyrównania, marginesy itp. Również tło tej części strony może mieć sens, nawet jeśli nie wydaje się być tak specyficzne dla układu.
Oto przykład jak to powinno wyglądać:
#header { background: #fcfcfc; } #header .l-right { float: right; } #header .l-align-center { text-align: center; }
Możesz również dodać te pomocniki dla wyrównań, których możesz użyć do łatwego pozycjonowania elementów, po prostu dodając odpowiednią klasę do jej elementu podrzędnego lub wyrównaj jej tekst.
Na przykład możesz użyć niektórych domyślnych marginesów w polu układu, takich jak .l .l-margin
o marginesie 20px
. Następnie, gdziekolwiek chcesz uzupełnić jakiś kontener, element, kartę lub pudełko, po prostu dodaj do niego klasę l-margin
. Ale chcesz czegoś wielokrotnego użytku:
.l-full-width { width: 100%; }
Nie coś wewnętrznie połączonego w ten sposób:
.l-width-25 { width: 25px; }
Chcę poświęcić chwilę na omówienie konwencji nazewnictwa w SMACSS. Jeśli nigdy nie słyszałeś o koncepcji przestrzeni nazw w CSS, to w zasadzie dodanie nazwy na początku innego elementu, aby pomóc odróżnić go od czegokolwiek innego. Ale dlaczego tego potrzebujemy?
Nie wiem, czy kiedykolwiek spotkałeś się z następującym problemem. Piszesz CSS i masz na czymś etykietę — dodajesz dowolne style i nazywasz swoją klasę .label
. Ale później dochodzisz do innego elementu i chcesz, aby był to .label
, ale stylizuj go w inny sposób. Tak więc dwie różne rzeczy mają tę samą nazwę – konflikt nazw.
Przestrzenie nazw pomagają rozwiązać ten problem. Ostatecznie nazywa się je tym samym na jednym poziomie, ale mają inną przestrzeń nazw — inny przedrostek — i dlatego mogą reprezentować dwa różne style:
.box--label { color: blue; } .card--label { color: red; }
Moduł
Jak wspomniałem wcześniej, moduły SMACSS to mniejsze fragmenty kodu, które można ponownie wykorzystać na stronie i są częścią jednego układu. Są to części CSS, które chcemy przechowywać w osobnym folderze, ponieważ będziemy mieć ich wiele na jednej stronie. A wraz z rozwojem projektu możemy podzielić według najlepszych praktyk dotyczących struktury folderów, tj. według modułów/stron:

Tak więc w poprzednim przykładzie mieliśmy artykuł, który może być samodzielnym modułem. Jaka powinna być tutaj struktura CSS? Powinniśmy mieć klasę .article
, która może zawierać elementy potomne title
i text
. Aby więc móc zachować go w tym samym module, musimy poprzedzić elementy potomne:
.article { background: #f32; } .article--title { font-size: 16px; } .article--text { font-size: 12px; }
Możesz zauważyć, że po przedrostku modułu używamy dwóch myślników. Powodem jest to, że czasami nazwy modułów mają dwa słowa lub własne przedrostki, takie jak big-article
. Potrzebujemy dwóch myślników, aby określić, jaka część jest elementem potomnym — np. porównaj big-article-title
big-article--title
i big-article--text
.
Możesz także zagnieżdżać moduły wewnątrz modułów, jeśli dany moduł zajmuje dużą część strony:
<div class="box"> <div class="box--label">This is box label</div> <ul class="box--list list"> <li class="list--li">Box list element</li> </ul> </div>
Tutaj, w tym prostym przykładzie, możesz zobaczyć, że box
jest modułem, a list
to kolejny moduł wewnątrz niego. Zatem list--li
jest dzieckiem modułu list
, a nie box
. Jednym z kluczowych pojęć tutaj jest użycie dwóch selektorów maksymalnie na każdą regułę CSS, ale w większości przypadków posiadanie tylko jednego selektora z prefiksami.
W ten sposób możemy uniknąć powielania reguł, a także posiadania dodatkowych selektorów na elementach podrzędnych o tych samych nazwach, poprawiając w ten sposób szybkość. Ale pomaga nam to również uniknąć używania niechcianych reguł w stylu !important
, które są oznaką słabo ustrukturyzowanych projektów CSS.
Dobrze (zwróć uwagę na pojedynczy selektor):
.red--box { background: #fafcfe; } .red-box--list { color: #000; }
Źle (zwróć uwagę na powtórzenia w selektorach i nakładającą się metodę odniesienia):
.red .box { background: #fafcfe; } .red .box .list { color: #000; } .box ul { color: #fafafa; }
Stan
To, co definiuje stan w SMACSS, to sposób na opisanie, jak nasze moduły wyglądają w różnych sytuacjach dynamicznych. Tak więc ta część jest tak naprawdę interaktywna: chcemy innego zachowania, jeśli element jest uważany za ukryty, rozwinięty lub zmodyfikowany. Na przykład akordeon jQuery będzie potrzebował pomocy w określeniu, kiedy możesz, a kiedy nie możesz zobaczyć zawartość elementu. Pomaga nam zdefiniować styl elementu w określonym czasie.
Stany są stosowane do tego samego elementu, co układ, więc dodajemy dodatkową regułę, która zastąpi poprzednie, jeśli takie istnieją. Zasada państwa ma pierwszeństwo, ponieważ jest ostatnią w łańcuchu reguł.
Podobnie jak w przypadku stylów układu, zwykle używamy tutaj przedrostków. To pomaga nam je rozpoznać i dać im pierwszeństwo. Tutaj używamy prefiksu is
, jak w is-hidden
lub is-selected
.
<header> <ul class="nav"> <li class="nav--item is-selected">Contact</li> <li class="nav--item">About</li> </ul> </header>
.nav--item.is-selected { color: #fff; }
Tutaj można użyć !important
, ponieważ stan jest często używany jako modyfikacja JavaScript, a nie podczas renderowania. Na przykład masz element, który jest ukryty podczas ładowania strony. Po kliknięciu przycisku chcesz to pokazać. Ale domyślna klasa wygląda tak:
.box .element { display: none; }
Więc jeśli po prostu dodasz to:
.is-shown { display: block; }
Pozostanie ukryty nawet po dodaniu klasy .is-shown
do elementu za pomocą JavaScript. Dzieje się tak, ponieważ pierwsza zasada jest głęboka na dwa poziomy i zastąpi ją.
Możesz więc zamiast tego zdefiniować klasę stanu w ten sposób:
.is-shown { display: block !important; }
W ten sposób odróżniamy modyfikatory stanu od modyfikatorów układu, które mają zastosowanie tylko przy początkowym wczytaniu strony. To zadziała teraz, zachowując zalety minimalnych selektorów.
Temat
Ten powinien być najbardziej oczywisty, ponieważ zawiera zasady podstawowych kolorów, kształtów, obramowań, cieni i tak dalej. W większości są to elementy, które powtarzają się w całej witrynie. Nie chcemy ich redefiniować za każdym razem, gdy je tworzymy. Zamiast tego chcemy zdefiniować unikalną klasę, którą dodamy dopiero później do domyślnego elementu.
.button-large { width: 60px; height: 60px; }
<button class="button-large">Like</button>
Nie myl tych reguł tematycznych SMACSS z podstawowymi, ponieważ podstawowe reguły dotyczą tylko domyślnego wyglądu i zwykle przypominają resetowanie do domyślnych ustawień przeglądarki, podczas gdy jednostka tematyczna jest bardziej rodzajem stylizacji, w której nadaje ostateczny wygląd, unikalny dla tej specyficznej kolorystyki.
Reguły motywów mogą być również przydatne, jeśli witryna ma więcej niż jeden styl lub może kilka motywów używanych w różnych stanach i dlatego można je łatwo zmienić lub zamienić podczas niektórych wydarzeń na stronie, np. za pomocą przycisku przełączania motywu. Przynajmniej utrzymują wszystkie style motywów w jednym miejscu, dzięki czemu można je łatwo zmieniać i ładnie je uporządkować.
Metodologie organizacji CSS
Omówiłem kilka kluczowych koncepcji tego pomysłu na architekturę CSS. Jeśli chcesz dowiedzieć się więcej o tej koncepcji, możesz odwiedzić oficjalną stronę SMACSS i zagłębić się w nią.
Tak, prawdopodobnie możesz użyć bardziej zaawansowanych metodologii, takich jak OOCSS i BEM. Ta ostatnia obejmuje prawie cały przepływ pracy frontendu i jego technologie. Selektory BEM mogą działać świetnie dla niektórych osób, ale niektórzy mogą uznać je za zbyt długie i przytłaczające, a także zbyt skomplikowane w użyciu. Jeśli potrzebujesz czegoś prostszego, łatwiejszego do opanowania i włączenia do swojego przepływu pracy — a także czegoś, co definiuje podstawowe zasady dla Ciebie i Twojego zespołu — SMACSS jest idealnym rozwiązaniem.
Nowi członkowie zespołu będą mogli z łatwością nie tylko zrozumieć, co zrobili poprzedni programiści, ale także od razu zacząć nad tym pracować, bez różnic w stylu kodowania. SMACSS to tylko architektura CSS i robi to, co mówi na puszce — nic więcej i nic mniej.