Tailwind CSS vs BEM - jak stylować strony?

Поделиться
HTML-код
  • Опубликовано: 9 ноя 2024

Комментарии • 13

  • @ComandeerPL
    @ComandeerPL 3 года назад +15

    BEM nie jest konwencją nazewniczą. Yandex stworzył go jako całościową metodykę tworzenia modularnych aplikacji webowych, w tym z całym toolingiem i strukturą plików, co można zobaczyć na oficjalnej stronie BEM-u (bem kropka info).
    BEM nie wiąże ściśle CSS-a z HTML-em. Jedynym punktem wspólnym są klasy, które de facto tworzą DSL do opisu struktury strony. I ten DSL można z powodzeniem wykorzystać poza CSS-em i HTML-em, choćby w JS-ie, ale także już na etapie projektowania strony. No i w BEM operujemy na abstrakcyjnej strukturze, jaką jest BEM Tree - nie bezpośrednio na HTML-u czy CSS-ie.
    Poza tym założenie, że przy BEM-ie cały CSS jest tworzony od podstaw, jest dość… dziwne. Nawet Bootstrap udostępnia mixiny, dzięki którym można złożyć stylowanie bez pisania go od podstaw. Ba, można wykorzystać Tailwindowe `@apply` do stworzenia arkuszy wykorzystujących konwencję nazewniczą BEM (czyli to, co w kontekście ACSS mówię od dawna - nie ACSS a ASCSS).
    Arkusze można bez problemu mieć małe i dostosowane wyłącznie do bloków, jakie są używane w danym projekcie/części projektu. BEM to w końcu też odpowiedni podział na pliki + tooling do budowy całości.
    AHA to termin ukuty przez Kent C. Doddsa i de facto nie funkcjonuje poza ekosystemem Reacta. Zresztą ta zasada polega na unikaniu przedwczesnych abstrakcji (co swoją drogą funkcjonuje od lat w programowaniu, tylko że bez nazwy; pisał o tym choćby Bevacqua w Mastering Modular JavaScript). Natomiast w przypadku projektowania aplikacji przy pomocy DSL-a, jakim jest konwencja nazewnicza BEM, nazwy odzwierciedlają role elementów. Sam nazywasz ten element navbarem - i tym jest to na poziomie BEM: blokiem navbar. Nie bardzo jest tutaj jakaś abstrakcja, raczej uspójnienie nazewnictwa między wszystkimi warstwami aplikacji webowej.
    A unikalnych komponentów w BEM nie powinno być, bo BEM dąży do jak największej generalizacji. Zresztą tak samo to powinno działać w Design Systemie: uspójnianie komponentów, nie tworzenie unikalnych.
    Owszem, designerzy mogą myśleć o layoucie w postaci design tokenów, tylko że to utrudnia znacząco komunikację pomiędzy nimi a całą resztą zespołu produktowego. BEM wprowadza wspólne nazewnictwo de facto na każdym poziomie i ułatwia komunikację.
    Zresztą nic nie stoi na przeszkodzie, żeby design tokenów używać także w BEM, bo jak sam zauważyłeś - nie wpływa on na to, jak konstruuje się arkusze stylów. Można mieć design tokeny jako zmienne czy to w preprocesorze, czy bezpośrednio w CSS-ie.
    Nie potrzeba Tailwinda do zachowania spójności. Samo istnienie Design Systemu czy nawet stworzenie biblioteki komponentów w BEM wymusza spójność.
    Zasady BEM są proste, wymogi dotyczące nazewnictwa to już raczej wewnątrzorganizacyjne ustalenia w poszczególnych zespołach. A te, jeśli są dobrze udokumentowane, to nie zezwalają na "dialekty" czy "regionalizmy".
    W BEM też łatwo sterować klasami przy pomocy JS-a. Różnica jest głównie w semantyce: Tailwind zmienia _wygląd_ komponentu, w BEM zmienia się _stan_ komponentu. No i łatwiej jest zmienić kilka rzeczy naraz w wyglądzie elementu przy zmianie jednej klasy, niż przy zmianie kilku (przy założeniu, że nie używamy w Tailwindzie `@apply`). W BEM dodatkowo zmiana stanu jest komunikatem zrozumiałym dla wszystkich warstw aplikacji (bo konwencja nazewnicza stanowi DSL), w Tailwindzie często zmiany nie mają sensu dla kodu, który je powoduje (zmiana stanu przycisku na "active" vs zmiana tła przycisku na zielony). Semantyka tych zmian jest całkowicie różna i dopóki rozpatrujemy to wyłącznie na poziomie HTML↔CSS, to, faktycznie, różnica ta jest pomijalna. W przypadku uspójniania nazewnictwa między Design Systemem, a poszczególnymi warstwami strony - już niekoniecznie.
    I oczywiście, że Tailwind łamie Separation of Concerns, bo warstwa prezentacji jest sterowana przez warstwę treści. Cały koncept "separation of concerns is not a separation of technology" powstał za czasów Reacta i osobiście uważam go za próbę wyjaśnienia, czemu powstał JSX. To, że aplikacje są dzielone na komponenty, nie znaczy, że te komponenty nie mogą być złożone z trzech niezależnych warstw. Choćby w Vue ten podział jest o wiele wyraźniejszy niż w Reakcie, dzięki Single File Components. Jak dla mnie komponenty to inny podział aplikacji niźli podział na warstwy treści, prezentacji i zachowania. Komponenty to podział wertykalny, warstwy - horyzontalny. I jak pokazuje Vue, wcale nie trzeba mieć trzech plików, żeby mieć trzy warstwy. Zresztą te trzy warstwy wynikają też choćby z tego, jak przeglądarki wczytują i renderują strony. A to, że sporo ludzi omija podział horyzontalny i to działa, nie jest za bardzo argumentem.
    A zmiany w HTML-u przy BEM-owym projekcie nie muszą (czy wręcz: nie powinny) wpływać na CSS z prostej przyczyny: struktura BEM jest niezależna od HTML i CSS. Jedynie zmiany w strukturze BEM wymuszą zmianę kodu CSS.
    Patrzenie przez pryzmat samych komponentów to nie jest "szersze" spojrzenie - ono jest właśnie węższe. Ten podział na "trzy pliki" (który jest fałszywy, o czym pisałem powyżej), wynika z samej natury technologii webowych i tego, jak są konstruowane. Progressive Enhancement działa dlatego, że HTML jest faktycznie jedynym pewnikiem, który dotrze do użytkownika. Stopniowe ulepszanie strony zakłada, że bazowe doświadczenie będzie zawsze, a w miarę możliwości urządzenia będzie się dokładać kolejne funkcje. Tak działa przecież cały feature detection w JS-ie czy fallbacki w CSS-ie (choćby stare `width: 100%; width: 100vh;` - starsze przeglądarki, bez obsługi `vh`, użyją `%`, a nowsze - `vh`). Podział na warstwy jest kierunkowany na użytkownika, podział na komponenty - na biznes i developera. To są dwa różne podziały służące dwóm różnym celom.
    A porównanie Tailwinda do inline styles wynika właśnie z tego, że Tailwind łamie separation of concerns i powoduje wyciek informacji o wyglądzie bezpośrednio do HTML-a. W tym zakresie jest de facto tożsamy ze stylami inline.
    BEM w 2015 już miał raczej ugruntowaną pozycję. To już były czasy CSS-in-JS, więc de facto początek końca świetności BEM jako, niestety, konwencji nazewniczej w CSS-ie. Sam BEM w obecnej formie powstał w 2010 roku.
    Na koniec powtórzę to, co zawsze powtarzam przy okazji ACSS czy utility first: fajne, ale jako preprocesor. Tailwinda właśnie widziałbym w tej roli - narzędzia do generowania stylów zgodnych z konwencją nazewniczą BEM przy użyciu `@apply`.

    • @Przeprogramowani
      @Przeprogramowani  3 года назад +2

      Aby łatwiej się odnieść się do poszczególnych argumentów, będę stosował numerację paragrafów.
      1. Zgadzam się, BEM jest czymś więcej niż konwencją nazewnictwa. Określenie tej metodyki w ten sposób było zbyt dużym uproszczeniem. Tym niemniej w swojej ocenie odnosiłem się do całości, a nie tylko części BEM, którą jest konwencja nazewnictwa.
      2. Czyli w takim razie wprowadzając zmiany w strukturze HTML naszego komponentu nie musimy wprowadzać zmian/usuwać klas CSS, które stylują tenże komponent? Oczywiście, że musimy, więc istnieje ścisłe powiązanie pomiędzy CSS a HTML. W Tailwind taka sytuacja nie zachodzi.
      3. Nic technicznie nie stoi na przeszkodzie, aby łączyć BEM z biblioteką mixinów SASS bądź frameworkiem utility-first. Nie sądzę, żebym wyraził taką opinię. Za to niewątpliwie korzystając z BEM przyjdzie nam pisać dużo kodu CSS/SCSS w porównaniu z klasycznym podejściem do Tailwinda. Do pomysłu łączenia Tailwinda z BEM odniosę się dalej.
      4. Zgadzam się, dokładnie o tym powiedziałem wymieniając plusy BEM.
      5. Nie wiem jak to, że termin AHA jest głównie używany w społeczności Reacta ma się do słuszności stosowania tej heurystyki w dowolnej technologii i samego argumentu podniesionego w filmie. Co do navbara, postępując zgodnie z zasadami BEM na samym navbarze się nie skończy. Pojawią się jeszcze navbar__itemy, modyfikator wskazujący, który z nich jest aktywny, być może jakieś zagnieżdżone bloki oraz elementy. Dużo roboty jak na komponent, który nigdy nie będzie ponownie użyty. W przypadku Tailwinda po prostu dodalibyśmy odpowiednie utility classy, nawet bez konieczności wydzielania komponentu prezentacyjnego.
      6. Generalizowanie jest jednym z powodów, dla których nazewnictwo jest tak trudne. Nie wiem czy uznawałbym to za plus :). W Design systemie uspójniamy za pomocą design tokenów, to kompletnie inne podejście.
      7. Jeżeli front end developer również pracuje na design tokenach za pośrednictwem utility class to ich komunikacja na ich linii jest efektywniejsza. Jednocześnie nie miałem styczności z PMem, który schodziłby na taki poziom detali jak wymaga tego BEM. Produkt patrzy na design na dużo wyższym poziomie abstrakcji.
      8. Zgadzam się, ale wymaga to więcej pracy i nadal naszą jedyną obroną przed wychodzeniem poza ramy design systemu pozostanie code review.
      9. Nie wymusza spójności, a jedynie pomaga w zachowaniu spójności. Klasy utility połączone z design systemem narzucają na nas jasne ograniczenia na poziomie interfejsu, do którego mamy dostęp. W przypadku BEM możemy zrobić co nam się żywnie podoba w stylesheetcie, i jedynie stylelint i koledzy z teamu mogą nas przed tym zatrzymać.
      10. Nic co związane z nazewnictwem nie jest proste. Nie mam na to żadnych badań, aczkolwiek nie przez przypadek ta opinia przewija się w tak wielu miejscach. W całym swoim wywodzie bardzo oszczędnie podszedłeś do tej kwestii, podczas gdy w moich oczach, i wielu osób, które obecnie przerzuciły się na Tailwinda, jest to jeden z głównych czynników przemawiających przeciwko BEM.
      11. Zgadzam się co do tego, że sterowanie klasami BEM za pomocą JS również nie sprawia kłopotów. Biorąc pod uwagę, że możemy nadać semantykę dla klas utility-first odpowiednio nazywając zmienną, która będzie nimi zarządzała np. activeClasses sprawia, że niespecjalnie przekonuje mnie to co napisałeś. Językiem design systemu są design tokeny, więc również nie przekonuje mnie to co napisałeś.
      12. Czasy Reacta trwają od kilku dobrych lat. To tak jakbym argumentował, że “Separation of concerns is a separation of technology” powstało przed czasami Reacta i osobiście uważam, że w tamtych czasach, znacznie odbiegających od tego co i jak budujemy w sieci, takie podejście miało jakikolwiek sens. W Vue masz jasną ingerencję warstwy zachowań w warstwę struktury za pomocą dyrektyw itd. Podział za pomocą tagów, plików, whatever z mojego punktu widzenia jest w dzisiejszych czasach symboliczny i nie wnosi wiele do tego jak ja myślę o komponentach, które tworzę.
      13. Jeżeli designerzy również pracują w oparciu o BEM to się zgadzam. Nie znam takowych, więc moim zdaniem argument oderwany od rzeczywistości.
      14. W świecie o ograniczonych zasobach, a w takim się znajdujemy, te dwa cele konkurują o nasz czas. Od persony użytkownika, dla którego budujemy konkretną aplikację/stronę zależy na ile istotne jest to co napisałeś w kontekście podziału na warstwy vs podział na komponenty.
      16. I to jest jedyny zakres tejże tożsamości, który pomija cały ogrom istotnych różnic, które wymieniłem w filmie. To tak jakby porównywać malunek 4-latka z pracą dyplomową studentki ASP, w końcu to jedno i drugie na papierze i wykonane za pomocą farb ;).
      15. A ja tego podejście nie polecam, bo jak pisałem wcześniej, nazewnictwo w moich oczach jest dużo trudniejsze niż wielu osobom się wydaje. Jeżeli możemy obniżyć ilość decyzji nazewniczych jakie podejmujemy w ramach projektu, to warto z takiej możliwości skorzystać.

    • @ComandeerPL
      @ComandeerPL 3 года назад +3

      @@Przeprogramowani rzeknę tak: większość z tego, co powiedziałeś, można podsumować prostym stwierdzeniem, że Tailwind jest lepszym rozwiązaniem do stylowania, bo programiści popełniają błędy. Więc to nie BEM jest problemem a interfejs białkowy…
      ad. 12) Podział warstwowy jest wpisany wprost do zasad tworzenia standardów sieciowych - HTML Design Principles od W3C, punkt 3.4 Separation of Concerns (linka nie podam, bo YT ich nie lubi…). Technologie sieciowe są tworzone w taki sposób, by niezależność warstw była zachowana. Dlatego tak, jak mówię, Tailwind łamie zasadę rozdziału odpowiedzialności, bo podział warstwowy jest inny niż podział na komponenty. To, jak mocno nas to ugryzie, zależy od projektu, ale im bardziej projekt ma być dostępny (w rozumieniu: available), tym bardziej brak warstw zaczyna być problemem.
      ad. 13) To, że Ty nie znasz, nie oznacza, że a) jest to argument oderwany od rzeczywistości b) nie jest to potencjalne wykorzystanie BEM. Jeśli wszyscy w projekcie używają tych samych nazw, komunikacja przebiega szybciej, bo wszyscy wiedzą, o czym jest mowa.
      ad. 15) Tylko że Tailwind rozwiązuje problem CSS-a, a BEM - całej architektury. Więc to jest dokładnie to, co opisywałeś w punkcie 16.: porównujesz dwie totalnie nieprzystające do siebie rzeczy.
      ad. 11) Nie, językiem design systemu nie są design tokeny. Design tokeny - używając żargonu językoznawczego - są leksemami, podstawowymi jednostkami budującymi design system. Ale same w sobie nie znaczą nic. Brad Frost w swoim Atomic Design stworzył dla nich osobną kategorię, subatomów. I dopiero połączone razem tworzą najbardziej podstawową część Atomic Design - atom. Zresztą tak funkcjonują praktycznie wszystkie design systemy, np. Spectrum od Adobe. Design tokeny określają podstawowe rzeczy i służą do budowy większych części design systemu, takich jak komponenty. Same w sobie design tokeny nie znaczą nic.
      ad. 5) A skąd założenie, że nie będzie? W tym danym projekcie może i nie, ale po to tworzy się Design System, żeby istniała spójność interfejsu _między_ projektami. Tworzenie Design Systemu po to, by go wykorzystać w jednym produkcie, jest mocnym overkillem.
      Niemniej modyfikator aktywnego linku wciąż jest wzięty wprost z designu. W końcu linki są aktywne i design musi to uwzględniać. Musi uwzględniać _stan_ poszczególnych elementów interfejsu. W Tailwindzie też ten stan uwzględniasz - ale wyłącznie na poziomie prezentacji. I w tym momencie IMO traci się sporo informacji.
      ad. 6) Design tokeny załatwiają najbardziej podstawowe rzeczy. Uspójnianie zachodzi jednak na wszystkich poziomach. Komponenty w ramach design systemów również są uspójniane. Dzięki temu np. nawigacja wszędzie stosuje te same wzorce.
      ad. 2) Nie, nie musimy, bo HTML i CSS komunikują się przy pomocy DSL-a, który służy do formowania drzewka BEM. Tak długo, jak zmiany w strukturze HTML nie są związane ze zmianą drzewka BEM, nie trzeba zmieniać kodu CSS.
      ad. 1) Rozumiem, że odnosiłeś się też do całego toolingu oraz proponowanej przez BEM struktury plików?

  • @AndrzejMazurEznawca
    @AndrzejMazurEznawca 3 года назад +8

    Trochę dziwne wydaje mi się porównanie BEM, które jest tylko metodologią czyli pewną ideą, która może być realizowana na dziesiątki sposobów, do konkretnego frameworka. Chętnie zobaczyłbym porównanie Tailwinda do Bootstrapa

    • @Przeprogramowani
      @Przeprogramowani  3 года назад +4

      Zdaje sobie sprawę, że porównałem jabłka do pomarańczy ale doszedłem do wniosków, że takie porównanie będzie ciekawsze. Tak się składa, że w projektach frontendowych często dokonujemy takiego wyboru, a Bootstrap, zwłaszcza w większych projektach, odchodzi do lamusa. BEM i klasyczne utility-first stoją w opozycji. Można zdecydować się na mix, ale daje to koślawy rezultat, w którym znacznie osłabiamy silne strony każdego z podejść, aby lekko załagodzić ich słabości.

  • @Krzysiekoy
    @Krzysiekoy 3 года назад +5

    Ja póki co siędzę cały czas w BEM. Do tej pory nie pracowałem z żadnym frameworkiem css-owym. Może kiedyś spróbuje tailwinda.
    Głównie przemawia do mnie to, że z tego co czytam to te klasy są przemyślane pod względem designu i spójności, a u mnie niestety zmysł estetyczny kuleje. Jeśli dzięki temu zyskam nieco na estetyce, to może być duży plus.
    Z drugiem strony bardzo podoba mi się prostota BEM. To tylko konwencja nazewnictwa; żadnych paczek, skryptów, configów. To jest ogromny plus BEM.

  • @leszekstubinski
    @leszekstubinski 3 года назад +5

    Co jest z tym dźwiękiem?

    • @Przeprogramowani
      @Przeprogramowani  3 года назад

      Najwidoczniej padł mi sterownik i dźwięk zbierał wbudowany mikrofon z Maca. Będę debuggował w weekend 😉

    • @PiotrNalepa
      @PiotrNalepa 3 года назад

      @@Przeprogramowani to dudnienie sprawia u mnie ból głowy

    • @Przeprogramowani
      @Przeprogramowani  3 года назад

      @@PiotrNalepa Od 5:35 gdy zaczyna się sedno odcinka jest już git 😉

  • @wafel_dev
    @wafel_dev 3 года назад +1

    Jak w tailwind ogarnąć sytuacje gdy komponent ma różne warianty? Powiedzmy jasny I ciemny motyw albo pełna/okrojona wersje? W bem wystarczy modyfikator na bloku typu - - light lub - - dark I mamy ogarniete. A w tailwind dodawanie poszczegolnych klas warunkowo?

    • @Przeprogramowani
      @Przeprogramowani  3 года назад

      Dokładnie, musisz to obsłużyć na poziomie interfejsu swojego komponentu i zarządzać klasami Tailwind za pomocą JSa 😉

  • @oziocb
    @oziocb 3 года назад

    BEM 4 life ! XD