Zalety używania właściwości niestandardowych w systemach projektowania i bibliotekach komponentów.
Mam na imię Dave i jestem starszym programistą frontendu w firmie Nordhealth. Zajmuję się projektowaniem i rozwojem naszego systemu projektowania Nord, który obejmuje m.in. tworzenie komponentów sieciowych do naszej biblioteki komponentów. Chcę opowiedzieć o tym, jak rozwiązaliśmy problemy związane ze stylem komponentów internetowych za pomocą właściwości niestandardowych CSS, a także inne korzyści płynące z używania właściwości niestandardowych w systemach projektowania i bibliotekach komponentów.
Jak tworzymy komponenty sieciowe
Do tworzenia komponentów sieciowych używamy Lit – biblioteki, która udostępnia wiele stałych elementów kodu, takich jak stan, style zakresu czy szablony. Jest ona nie tylko lekka, lecz oparta na natywnych interfejsach API JavaScript, dzięki czemu możemy dostarczać nieduży pakiet kodu wykorzystujący funkcje dostępne w przeglądarce.
Najbardziej atrakcyjną cechą komponentów sieciowych jest to, że współpracują z prawie każdą istniejącą platformą JavaScript lub nawet nie obsługują żadnej. Gdy na stronie pojawi się odwołanie do głównego pakietu JavaScript, korzystanie z komponentu internetowego przypomina używanie natywnego elementu HTML. Jedynym rzeczywistym znakiem, który sygnalizuje, że nie jest to natywny element HTML, jest spójny łącznik w tagach, który jest standardem wskazującym przeglądarce, że jest to komponent internetowy.
Herbata cienia w stylu DOM
W podobny sposób natywne elementy HTML mają model Shadow DOM, podobnie jak komponenty sieciowe. Shadow DOM to ukryte drzewo węzłów w elemencie. Aby to zwizualizować, najlepiej otwórz inspektora sieci i włącz opcję „Pokaż drzewo DOM DOM”. Gdy to zrobisz, przyjrzyj się natywnym elementom wejściowym w inspektorze – pojawi się możliwość otworzenia tych danych wejściowych i obejrzenia wszystkich zawartych w nich elementów. Możesz nawet wypróbować ten komponent z jednym z naszych komponentów sieciowych – sprawdź nasz niestandardowy komponent do wprowadzania danych, aby zobaczyć model DOM.
Jedną z zalet (lub wad – w zależności od wizji) architekturze Shadow DOM jest hermetyzacja stylów. Jeśli tworzysz kod CSS w komponencie internetowym, style te nie mogą wyciekać ani wpływać na stronę główną ani inne elementy. Są one w całości zawarte w komponencie. Kod CSS napisany dla strony głównej lub nadrzędnego komponentu internetowego nie może również wyciekać do komponentu internetowego.
Takie zakończenie stylów jest jedną z korzyści w naszej bibliotece komponentów. Daje nam to większą pewność, że gdy ktoś użyje jednego z naszych komponentów, będzie on wyglądał zgodnie z oczekiwaniami, niezależnie od stylów zastosowanych na stronie nadrzędnej. Aby jeszcze bardziej zyskać pewność, dodajemy atrybut all: unset;
do katalogu głównego, czyli „hosta” wszystkich naszych komponentów sieciowych.
Co jednak zrobić, jeśli osoba korzystająca z Twojego komponentu internetowego ma uzasadniony powód, by zmienić niektóre style? Może jeden wiersz tekstu wymaga większego kontrastu ze względu na kontekst lub obramowanie trzeba zwiększyć? Jak możesz odblokować te opcje stylu, jeśli do komponentu nie dostają się żadne style?
Właśnie tu do akcji wkraczają właściwości niestandardowe CSS.
Właściwości niestandardowe CSS
Właściwości niestandardowe mają bardzo odpowiednią nazwę – są to właściwości CSS, które możesz samodzielnie nazwać i zastosować dowolną wartość. Jedynym wymaganiem jest dodanie do nich dwóch łączników. Po zadeklarowaniu właściwości niestandardowej możesz jej używać w CSS za pomocą funkcji var()
.
W przypadku dziedziczenia wszystkie właściwości niestandardowe są dziedziczone zgodnie z typowym zachowaniem zwykłych właściwości i wartości CSS. Dowolna niestandardowa właściwość zastosowana do elementu nadrzędnego lub samego elementu może być używana jako wartość w innych usługach. Właściwości niestandardowe wykorzystujemy w naszych tokenach projektowych do elementu głównego za pomocą naszej struktury CSS. Oznacza to, że wszystkie elementy na stronie mogą korzystać z tych wartości, niezależnie od tego, czy jest to komponent internetowy, klasa pomocnicza CSS, czy programista, który chce pobrać wartość z naszej listy tokenów.
Dzięki tej możliwości dziedziczenia właściwości niestandardowych przy użyciu funkcji var()
przebijamy się przez model DOM dla komponentów sieciowych, umożliwiając programistom większą kontrolę nad stylem komponentów.
Właściwości niestandardowe w komponencie Nord Web
Za każdym razem, gdy opracowujemy komponent naszego systemu projektowania, uważnie podchodzimy do jego stylu CSS – zależy nam na tym, by kod był jak najjaśniejszy, ale łatwy w użyciu. Tokeny projektowe są zdefiniowane jako właściwości niestandardowe w głównej strukturze CSS w elemencie głównym.
Wartości tokena są przywoływane w komponentach. W niektórych przypadkach zastosujemy wartość bezpośrednio w usłudze CSS, a w innych zdefiniujemy nową kontekstową usługę niestandardową i zastosujemy do niej wartość.
Wyodrębnimy też niektóre wartości charakterystyczne dla komponentu, ale nie w tokenach, i przekształcimy je w kontekstową usługę niestandardową. Właściwości niestandardowe związane z kontekstem komponentu mają 2 główne zalety. Po pierwsze, nasz kod CSS może zapewnić większą „suchość”, ponieważ tę wartość można zastosować do wielu właściwości w komponencie.
Po drugie, stan komponentu i odmiana są bardzo przejrzyste – aby zaktualizować wszystkie te właściwości, trzeba na przykład zmienić tylko właściwość niestandardową, gdy np. określisz styl stanu najechania, stanu aktywności lub, w tym przypadku odmiany.
Największą zaletą jest to, że kiedy zdefiniujemy kontekstowe właściwości niestandardowe w komponencie, tworzymy dla każdego z naszych komponentów niestandardowy interfejs CSS API, z którego może skorzystać użytkownik danego komponentu.
Poprzedni przykład przedstawia jeden z naszych komponentów sieciowych z kontekstową usługą niestandardową zmienioną za pomocą selektora. W efekcie takie podejście zapewnia użytkownikom wystarczającą elastyczność w określaniu stylu, a jednocześnie pozwala zachować zgodność z większością rzeczywistych stylów. Dodatkowo jako deweloperzy komponentów możemy przechwytywać style zastosowane 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.
Takie podejście jest niezwykle skuteczne nie tylko dla nas, jako twórców komponentów systemu projektowania, ale także dla naszego zespołu programistów, który wykorzystuje je w naszych produktach i usługach.
Ulepszamy właściwości niestandardowe
Obecnie nie ujawniamy w naszej dokumentacji kontekstowych właściwości niestandardowych, ale planujemy tak, aby nasz większy zespół programistów mógł je zrozumieć i wykorzystać. Nasze komponenty są spakowane do npm w pliku manifestu, który zawiera wszystkie informacje na ich temat. Plik manifestu jest następnie przetwarzany jako dane po wdrożeniu naszej witryny z dokumentacją. Można to zrobić przy użyciu usługi Eleventy i jej funkcji danych globalnych. Planujemy uwzględnić te kontekstowe właściwości niestandardowe w tym pliku danych manifestu.
Kolejnym obszarem, który chcemy poprawić, jest sposób, w jaki kontekstowe właściwości niestandardowe dziedziczą wartości. Jeśli na przykład chcesz zmienić kolor dwóch komponentów rozdzielających, musisz zastosować kierowanie na oba komponenty za pomocą selektorów lub zastosować właściwość niestandardową bezpośrednio do elementu z atrybutem stylu. Może się to wydawać normalne, ale lepiej byłoby, gdyby deweloper mógł definiować te style na poziomie elementu nadrzędnego lub nawet na poziomie głównym.
Musisz ustawić wartość właściwości niestandardowej bezpośrednio w komponencie, ponieważ definiujemy ją w tym samym elemencie za pomocą selektora hosta komponentu. Globalne tokeny projektowe, których używamy bezpośrednio w komponencie, przechodzą bezpośrednio, ten problem nie ma na niego wpływu, a nawet mogą być przechwytywane w elementach nadrzędnych. Jak możemy połączyć to, co najlepsze?
Prywatne i publiczne właściwości niestandardowe
Prywatne właściwości niestandardowe utworzyła Lea Verou. Są one kontekstową „prywatną” właściwością niestandardową w samym komponencie, ale ustawioną jako „publiczną” właściwość niestandardową z zastępczą wartością.
Jeśli skonfigurujesz kontekstowe właściwości niestandardowe w taki sposób, nadal możemy wykonywać te same czynności, co do tej pory, na przykład dziedziczyć wartości tokenów globalnych i ponownie ich używać w całym kodzie komponentu. Będzie też płynnie dziedziczyć nowe definicje właściwości samej lub dowolnego elementu nadrzędnego.
Chociaż można argumentować, że ta metoda nie jest w pełni „prywatna”, to wciąż sądzimy, że jest to dość eleganckie rozwiązanie problemu, którego się martwiliśmy. Gdy pojawi się taka możliwość, zajmiemy się tą sprawą w naszych komponentach, tak aby nasz zespół programistów miał większą kontrolę nad ich wykorzystywaniem, a jednocześnie nadal korzystał z naszych barier.
Mam nadzieję, że udało mi się zrozumieć, jak korzystamy z komponentów sieciowych z właściwościami niestandardowymi CSS. Jeśli zdecydujesz się wykorzystać którąś z tych metod w swojej pracy, daj nam znać, co o tym myślisz. Możesz mnie też znaleźć na Twitterze: @DavidDarnes. Możesz też odwiedzić konto Nordhealth @NordhealthHQ na Twitterze oraz inne osoby z mojego zespołu, które ciężko pracowały nad połączeniem tego systemu projektowania i wdrożeniem funkcji opisanych w tym artykule: @Viljamis, @WickyNilliams i @eric_habich.
Baner powitalny: Dan Cristian Pădure Reklamy