Zalety korzystania z właściwości niestandardowych w systemach projektowych i bibliotekach komponentów.
Nazywam się Dave i pracuję jako starszy programista front-endu w firmie Nordhealth. Pracuję nad projektem i rozwojem naszego systemu projektowego Nord, który obejmuje tworzenie komponentów internetowych do naszej biblioteki komponentów. Chcę opowiedzieć, jak rozwiązaliśmy problemy związane ze stylizacją komponentów internetowych, używając właściwości niestandardowych CSS, oraz o niektórych innych zaletach korzystania z właściwości niestandardowych w systemach projektowania i bibliotekach komponentów.
Jak tworzymy komponenty sieciowe
Do tworzenia naszych komponentów sieciowych używamy biblioteki Lit, która zawiera wiele gotowych fragmentów kodu, takich jak stan, style zakresu czy szablony. Jest nie tylko uproszczony, ale jest też oparty na natywnych interfejsach API JavaScriptu, co oznacza, że możemy dostarczyć nieskomplikowany pakiet kodu, który wykorzystuje funkcje, które już mamy w przeglądarce.
Największą zaletą komponentów internetowych jest jednak to, że działają one z prawie każdym istniejącym frameworkiem JavaScriptu, a nawet bez frameworka. Kiedy na stronie jest odwołanie do głównego pakietu JavaScriptu, używanie komponentu internetowego przypomina używanie natywnego elementu HTML. Jedynym prawdziwym znakiem, że nie jest to natywny element HTML, jest konsekwentne używanie myślnika w tagach, co jest standardem oznaczającym dla przeglądarki, że jest to komponent internetowy.
Kodowanie stylu Shadow DOM
Podobnie jak natywne elementy HTML mają model Shadow DOM, tak samo jest w przypadku komponentów internetowych. Shadow DOM to ukryte drzewo węzłów w elemencie. Najlepszym sposobem, aby to zobaczyć, jest otwarcie inspektora sieci i włączenie opcji „Pokaż drzewo DOM Shadow”. Następnie w inspektorze sprawdź element domyślnego wejścia. Teraz możesz otworzyć to wejście i zobaczyć wszystkie jego elementy. Możesz to też wypróbować z jednym z naszych komponentów sieciowych. Sprawdź nasz niestandardowy komponent do wprowadzania danych, aby zobaczyć jego DOM.
Jedną z zalet (lub wad – zależnie od programu) funkcji Shadow DOM jest hermetyzacja stylu. Jeśli napiszesz kod CSS w komponencie internetowym, te style nie będą mogły przenikać na stronę główną ani inne elementy. Będą one całkowicie zawarte w komponencie. Oprócz tego kod CSS napisany dla strony głównej lub nadrzędnego komponentu internetowego nie może wyciekać do komponentu internetowego.
To uwzględnienie stylów to jedna z korzyści dostępnych w naszej bibliotece komponentów. Dzięki temu mamy większą pewność, że gdy ktoś użyje jednego z naszych komponentów, będzie on wyglądał tak, jak chcieliśmy, niezależnie od stylów zastosowanych na stronie nadrzędnej. Aby jeszcze bardziej to ułatwić, dodaliśmy all: unset;
do katalogu głównego (czyli „hosta”) wszystkich naszych komponentów internetowych.
Co jednak w sytuacji, gdy użytkownik korzystający z komponentu internetowego ma uzasadniony powód, by zmienić określone style? Może jakiś wiersz tekstu wymaga większego kontrastu ze względu na kontekst lub obramowanie musi być grubsze? Jeśli żadne style nie mogą zostać zastosowane do Twojego komponentu, jak możesz odblokować te opcje stylizacji?
Dlatego do akcji wkraczają niestandardowe właściwości CSS.
Właściwości niestandardowe w CSS
Właściwości niestandardowe mają bardzo prawidłową nazwę – są to właściwości CSS, które możesz nazwać samodzielnie i zastosować dowolną potrzebną wartość. Wymaga to tylko dodania 2 łączników. Po zadeklarowaniu właściwości niestandardowej możesz używać jej wartości w CSS za pomocą funkcji var()
.
Jeśli chodzi o dziedziczenie, wszystkie właściwości niestandardowe są dziedziczone, co jest zgodne z typowym zachowaniem zwykłych właściwości i wartości CSS. Niestandardowych właściwości zastosowanych do elementu nadrzędnego lub samego elementu można używać jako wartości w innych właściwościach. Bardzo intensywnie korzystamy z właściwości niestandardowych w przypadku tokenów projektowych, stosując je do elementu głównego za pomocą platformy CSS Framework. Oznacza to, że wszystkie elementy na stronie mogą ich używać, niezależnie od tego, czy jest to komponent internetowy, klasa pomocnicza CSS czy programista chcący uzyskać wartość z naszej listy tokenów.
Ta zdolność do dziedziczenia właściwości niestandardowych za pomocą funkcji var()
pozwala nam omijać DOM cieniowy naszych komponentów internetowych i umożliwia deweloperom bardziej szczegółową kontrolę nad stylami komponentów.
Właściwości niestandardowe w komponencie Nord Web
Kiedy opracowujemy komponent do naszego systemu projektowego, stosujemy przemyślane podejście do jego CSS – staramy się stworzyć kod łatwy w użyciu, ale przy tym łatwy w utrzymaniu. Nasze tokeny projektowe są zdefiniowane jako właściwości niestandardowe w głównym interfejsie CSS w elemencie głównym.
Wartości tokenów są następnie przywoływane w naszych komponentach. W niektórych przypadkach zastosujemy wartość bezpośrednio w usłudze porównywania cen, ale w innych przypadkach zdefiniujemy nową kontekstową usługę spersonalizowaną i zastosujemy do niej wartość.
Utworzymy też abstrakcyjne wartości, które są specyficzne dla danego komponentu, ale nie występują w naszych tokenach, i przekształcimy je w kontekstualną właściwość niestandardową. Właściwości niestandardowe, które odnoszą się do komponentu, mają 2 główne zalety. Po pierwsze, oznacza to, że możemy bardziej „wyschnąć” z CSS, ponieważ wartość można zastosować do wielu właściwości w komponencie.
Po drugie, ułatwia to wprowadzanie zmian w stanie komponentu i wariantach – wystarczy zmienić tylko właściwość niestandardową, aby zaktualizować wszystkie te właściwości, gdy na przykład stylizujesz stan najechania kursorem lub stan aktywny albo w tym przypadku wariant.
Największą zaletą jest jednak to, że gdy definiujemy te kontekstowe właściwości niestandardowe w komponencie, tworzymy dla każdego z naszych komponentów rodzaj niestandardowego interfejsu API CSS, z którego może korzystać użytkownik tego komponentu.
Poprzedni przykład przedstawia jeden z naszych Komponentów sieciowych z kontekstową właściwością niestandardową zmienioną za pomocą selektora. Efektem tego podejścia jest komponent, który zapewnia użytkownikowi wystarczającą elastyczność stylizacji, zachowując przy tym kontrolę nad większością rzeczywistych stylów. Dodatkowo, jako deweloperzy komponentów mamy możliwość przechwytywania stylów zastosowanych przez użytkownika. Jeśli chcemy dostosować lub rozszerzyć jedną z tych właściwości, możemy to zrobić bez konieczności zmiany kodu przez użytkownika.
Uważamy, że to podejście jest bardzo skuteczne nie tylko dla nas jako twórców komponentów systemu projektowania, ale też dla naszego zespołu programistów, który używa tych komponentów w naszych usługach.
Rozszerzanie właściwości niestandardowych
W momencie pisania tego artykułu nie ujawniamy tych kontekstowych usług w dokumentacji, ale planujemy to zrobić, aby nasz szerszy zespół programistów mógł je zrozumieć i wykorzystać. Nasze komponenty są spakowane w npm w pliku manifestu, który zawiera wszystkie potrzebne informacje na ich temat. Następnie używamy pliku manifestu jako danych po wdrożeniu naszej witryny z dokumentacją, co odbywa się za pomocą usługi Eleventy i jej funkcji Dane globalne. Planujemy uwzględnić te kontekstowe właściwości niestandardowe w tym pliku danych manifestu.
Innym obszarem, który chcemy ulepszyć, jest sposób, w jaki te kontekstowe usługi niestandardowe dziedziczą wartości. Jeśli na przykład chcesz dostosować kolor dwóch komponentów separatora, musisz ustawić kierowanie na oba komponenty za pomocą selektorów lub zastosować właściwość niestandardową bezpośrednio do elementu z atrybutem style. Może się to wydawać w porządku, ale lepiej byłoby, gdyby deweloper mógł zdefiniować te style w elemencie zawierającym lub nawet na poziomie katalogu głównego.
Wartość właściwości niestandardowej musisz ustawić bezpośrednio w komponencie, ponieważ definiujemy je w tym samym elemencie za pomocą selektora hosta komponentu. Globalne tokeny projektu, których używamy bezpośrednio w komponencie, przechodzą od razu, nie mają na nie wpływu, a nawet mogą być przechwytywane w elementach nadrzędnych. Jak możemy korzystać z możliwości obu tych usług?
Prywatne i publiczne usługi niestandardowe
Prywatne właściwości niestandardowe to usługa, która została ustanowiona przez Lea Verou. Jest to kontekstowa „prywatna” właściwość niestandardowa w samym komponencie, ale ustawiona jako „publiczna” właściwość niestandardowa z wartością zastępczą.
Definiowanie kontekstowych właściwości niestandardowych w taki sposób oznacza, że nadal możemy wykonywać wszystkie czynności, które wykonywaliśmy wcześniej, np. dziedziczyć wartości globalnych tokenów i wykorzystywać wartości w kodzie komponentu. Komponent będzie też płynnie dziedziczyć nowe definicje tej właściwości w sobie lub w dowolnym elemencie nadrzędnym.
Chociaż można argumentować, że ta metoda nie jest naprawdę „prywatna”, uważamy, że jest to dość eleganckie rozwiązanie problemu, który nas niepokoił. Gdy tylko będzie to możliwe, rozwiążemy ten problem w naszych komponentach, aby nasz zespół programistów miał większą kontrolę nad ich używaniem, a jednocześnie mógł korzystać z dostępnych zabezpieczeń.
Mam nadzieję, że te informacje o tym, jak używamy komponentów internetowych z właściwościami niestandardowymi w CSS, były dla Ciebie przydatne. Daj nam znać, co o tym myślisz. Jeśli zdecydujesz się użyć którejś z tych metod w swojej pracy, możesz mnie znaleźć na Twitterze pod adresem @DavidDarnes. Na Twitterze znajdziesz także Nordhealth @NordhealthHQ na Twitterze, a także innych członków mojego zespołu, którzy ciężko pracują nad połączeniem tego systemu projektowania i wykonaniem funkcji opisanych w tym artykule: @Viljamis, @WickyNilliams i @eric_habich.
Baner powitalny: Dan Cristian Pădureț