Dark mode w aplikacjach Bubble

Tradycyjny sposób implementacji dark mode w aplikacji Bubble za pomocą wyrażeń warunkowych jest prosty, ale posiada wiele wad. Z artykułu dowiesz się jak bez korzystania z pluginów wdrożyć elastyczny i skalowalny mechanizm zmiany kolorystyki layoutu przez użytkownika aplikacji.

Tradycyjny sposób implementacji dark mode w Bubble

W internecie możesz znaleźć wiele poradników na temat “jak dodać dark mode do aplikacji Bubble”. Większość z nich opiera się na prostej koncepcji dodawania wyrażeń warunkowych (conditionals) do każdego elementu z osobna.

Implementacja dark mode za pomocą wyrażeń warunkowych w Bubble

Takie rozwiązanie jest proste do wdrożenia, ale posiada kilka wad, które ujawniają się dopiero w trakcie prac nad aplikacją:

Konieczność edycji pojedynczych elementów

Wyrażenia warunkowe zmieniające kolor elementu w zależności od preferencji użytkownika musisz dodać do każdego pojedynczego obiektu w aplikacji. Przy złożonych projektach oznacza to dodatkowe dziesiątki godzin spędzonych wyłącznie na dodawaniu kolorów do layoutu.

Co prawda część z tych wyrażeń warunkowych można zaimplementować w stylach globalnych, ale edytor pozwala na użycie tylko najprostszych warunków. Można więc sprawdzić, czy pole ‘darkMode’ ma wartość ‘yes’, ale warunkowanie na wartości ‘Display’ z ‘Option Set’ jest już niemożliwe.

Ograniczony zakres wyrażeń warunkowych w panelu Styles

Widoczne opóźnienie podczas renderowania zmienionych kolorów

Wyrażenia warunkowe na elementach wyzwalane są dosyć późno podczas ładowania kodu aplikacji. Przy wielu operacjach, które wykonywane są wcześniej (np. podczas eventu Page is loaded) wyraźnie widoczny będzie moment zmiany koloru elementu z domyślnego na ten określony w wyrażeniu warunkowym.

Ograniczona liczba dostępnych zmiennych kolorystycznych

Jeśli korzystasz z rozbudowanych design systemów (np. Material) to limit 32 zmiennych kolorystycznych okaże się zbyt mały do obsłużenia podstawowej palety kolorystycznej, nie wspominając już o dodatkowym dark mode. W rezultacie w wyrażeniach warunkowych będziesz korzystać z literałów, czyli “na sztywno” wprowadzonych wartości kolorystycznych. Takie podejście jest podane na błędy i literówki, mało skalowalne i niepotrzebnie zwiększające objętość kodu aplikacji.

Dark mode i dodatkowe palety kolorów w aplikacjach Bubble

Grupą docelową jednej z budowanych przeze mnie aplikacji są zawodowi developerzy. Projektując jej wygląd chciałem, żeby wrażenia użytkownika były jak najbardziej zbliżone do wzorców UX/UI znanych z najpopularniejszych narzędzi programistycznych. Jedną z funkcji miała być możliwość wyboru palety kolorystycznej interfejsu przez użytkownika.

Jeśli skorzystałbym z opisanego wyżej tradycyjnego podejścia to dodanie nowego schematu barw do aplikacji wymagałoby ode mnie dodania nowych wyrażeń warunkowych do każdego obiektu w aplikacji z osobna.

Żeby nie marnować niepotrzebnie czasu zastosowałem prostą sztuczkę – dynamicznie zmieniam wartości zmiennych kolorystycznych (CSS custom properties / color variables) w zależności od preferencji użytkownika.

Oto kilka zalet tej metody nad tradycyjnym podejściem:

  1. Możesz dodać dowolną liczbę palet barw do aplikacji i przechowywać je np. jako Option Set. Istnieje tylko jedno ograniczenie – liczba tokenów kolorystycznych w każdej palecie nie może przekroczyć 32, czyli liczby zmiennych dostępnych w edytorze Bubble.
  2. Jeśli chcesz dodać nową paletę kolorów do aplikacji to nie musisz robić żadnych zmian w istniejącym layoucie. Wystarczy, że dodasz nową opcję do Option Set, a element HTML podmieni wartość zmiennych kolorystycznych w zależności od aktualnego wyboru użytkownika.
  3. Jeśli element HTML odpowiedzialny za nadpisywanie wartości zmiennych umieścisz na samej górze każdej strony, to kolory będą aktualizowane na bardzo wczesnym etapie ładowania aplikacji. Użytkownik nie będzie widział “mignięcia” domyślnych kolorów.
  4. Korzystając z tej metody, dark mode (lub więcej dodatkowych palet kolorystycznych) dodasz do już istniejącej i dowolnie rozbudowanej aplikacji. Jest tylko jeden warunek – wszystkie elementy muszą być ostylowane za pomocą natywnych dla Bubble zmiennych kolorystycznych.
  5. BONUS: nie musisz korzystać z pluginów lub niestandardowego kodu JS i tym samym spowalniać działania swojej aplikacji.

Dark mode z możliwością wyboru palety kolorów przez użytkownika

Wdrożenie dark mode w aplikacjach Bubble według wspomnianego wcześniej sposobu składa się z kilku etapów.

Krok 1: stwórz zestaw zmiennych kolorystycznych i nadaj im domyślne wartości

W zakładce Styles > Style variables stwórz zestaw zmiennych i przypisz im kolory z Twojej podstawowej palety. W zasadzie, na tym etapie możesz wybrać dowolne barwy (ponieważ później i tak będą nadpisywane), ale domyślne kolory będą widoczne w edytorze, więc dla własnej wygody warto nadać im wartości odpowiadające rzeczywistości.

Domyślne wartości zmiennych kolorystycznych w aplikacji Bubble

Krok 2: stwórz Option Set, w którym będziesz przechowywać wartości kolorów dla każdej palety

W panelu Data > Option Sets utwórz nowy zestaw opcji – nazwij go colorScheme, colorPalette lub podobnie. Każda opcja w zestawie powinna składać się z listy atrybutów o typie Text i nazwach odpowiadających wprowadzonym wcześniej zmiennym. Zbieżne nazwy nie są wymogiem, ale znacząco ułatwiają pracę. Wartościami poszczególnych atrybutów są kody kolorów odpowiednie dla danej palety.

Przykład z mojej aplikacji:

OPTION SET NAME: OS_colorPalette
– Default dark
––– c-background: #0D0D0D
––– c-layer: #404040
––– c-font-primary: #F2F2F2
[...]
– Default light
––– c-background: #F2F2F2
––– c-layer: #BFBFBF
––– c-font-primary: #0D0D0D

Krok 3: zbuduj mechanizm wyboru schematu kolorystycznego przez użytkownika

W pierwszej kolejności w Data Type ‘User’ stwórz pole, w którym będziesz przechowywać wybraną przez użytkownika paletę kolorystyczną. W moim przypadku jest to pole o nazwie ‘colorPalette’ o typie ‘OS_colorPalette’ i wartości domyślnej ustawionej na ‘Default dark’.

Następnie w swojej aplikacji zbuduj mechanizm wyboru i zapisywania wybranej palety przez użytkownika. Na wcześniejszym wideo widoczne było moje rozwiązanie – prosty dropdown, który jako ‘Data source’ pobierał listę wszystkich opcji z ‘OS_colorPalette’.

Krok 4: pobierz systemowe nazwy używanych zmiennych kolorystycznych

Uruchom stronę główną swojej aplikacji (index) w przeglądarce, a następnie otwórz rozszerzenie DevTools. W panelu Elements podświetl nadrzędny tag <html>. W panelu Styles znajdź listę wszystkich zmiennych kolorystycznych (prawdopodobnie będzie zapisana w klasie b-root), a następnie skopiuj ją i wklej do dowolnego edytora tekstu.

Zmienne kolorystyczne aplikacji widoczne w DevTools

Skopiowaną listę sformatuj w taki sposób, aby była prawidłowym tagiem ‘style’:

  • otocz listę znacznikami <style>,
  • przypisz definicje do pseudoklasy ‘root’,
  • usuń duplikaty (pozycje z suffixem _rgb),
  • na podstawie przypisanych wartości RGB zidentyfikuj, która nazwa zmiennej stworzona automatycznie przez Bubble odpowiada twoim nazwom zmiennych. Dla ułatwienia dodaj odpowiednie komentarze,
  • usuń wartości kolorów dla każdej zmiennej i dopisz właściwość ‘!important’ do wszystkich pozycji.

Poniżej sformatowana lista zmiennych kolorystycznych z mojej aplikacji:

root: {
    /* c-background */
    --color_bTGyP_default:  !important;

    /* c-container */ 
    --color_bTGyQ_default:  !important;

    /* c-layer */
    --color_bTGyR_default:  !important;
   
    /* ... */
}

Krok 5: Dodaj dynamiczny arkusz stylów do aplikacji Bubble

Na każdej stronie swojej aplikacji dodaj nowy element HTML. Obiekt powinien być umiejscowiony jako pierwszy na stronie, dzięki czemu podmiana kolorów nastąpi przed wyświetleniem pozostałych elementów.

W swojej aplikacji rozwiązałem to za pomocą elementu reużywalnego (reusable element), który umiejscowiony jest jako pierwszy na liście elementów (elements tree) każdej podstrony. Wewnątrz niego znajduje się element HTML o rozmiarze 1×1 px.

W pole z treścią tego elementu wklej opracowaną w poprzednim punkcie listę. Każdą deklarację uzupełnij wyrażeniem dynamicznym, odwołującym się do koloru zapisanego w Option Set pod parametrem odpowiadającym danej zmiennej.

Fragment z mojej aplikacji:

  :root {
    /* c-background */
    --color_bTGyP_default: Current User's colorPalette's c-background !important;

    /* c-container */  
    --color_bTGyQ_default: Current User's colorPalette's c-container !important;

    /* c-layer */
    --color_bTGyR_default: Current User's colorPalette's c-layer !important;
    
    /* ... */
  }

W utworzonym właśnie elemencie HTML następuje nadpisywanie domyślnych wartości zmiennych kolorystycznych na te wartości, które są przechowywane w bazie danych zalogowanego użytkownika. Gdy tylko element zostanie wczytany w całości, wykonywane jest zapytanie do bazy danych, które zwraca wybraną przez użytkownika paletę kolorów oraz wszystkie jej wartości. Kolejne elementy na stronie renderowane są już przy użyciu nadpisanych kolorów.

Na koniec – w edytowanym elemencie warto zaznaczyć checkboxa ‘Wait to render this element until it is visible’ – powinno to zapobiec nadpisaniu zmiennych pustymi wartościami, jeśli odwołanie do bazy danych będzie trwało dłużej niż zwykle.

Dark mode i paleta kolorów zależna od ustawień przeglądarki

Istnieje prostsza metoda implementacji powyższej metody, w której użytkownik nie ma możliwości wyboru palety kolorystycznej, ale ta ustawiana jest w zależności od ustawień przeglądarki.

Procedura jest podobna do opisanej wyżej:

  1. Powtarzasz krok pierwszy, czyli ustawiasz listę zmiennych kolorystycznych dla swojej aplikacji nadając im dowolne domyślne kolory.
  2. Pomijasz krok drugi i trzeci, dzięki którym aplikacja przechowywała preferencje użytkownika w bazie danych. Teraz kolorystykę layoutu uzależniamy od ustawień przeglądarki, więc nie ma potrzeby zapisywania tych informacji w bazie. Aplikacja będzie je odczytywać podczas każdego ładowania stron.
  3. Powtarzasz krok czwarty, czyli kopiujesz i formatujesz listę zmiennych. Kod odpowiedzialny za nadpisywanie zmiennych kolorystycznych będzie miał jednak nieco inną treść. Wykorzystujemy w nim natywną funkcję CSS, która rozpoznaje ustawienia przeglądarki aktualnego użytkownika – także niezalogowanego.

Przykładowy kod:

    @media (prefers-color-scheme: dark) {
    	:root {
           --color_text_default: #FFFFFF !important;
           --color_background_default: #000000 !important;
        }
    }
    
    @media (prefers-color-scheme: light) {
        :root {
        	--color_text_default: #000000 !important;
           	--color_background_default: #FFFFFF !important;
        }
    }

Na koniec powtarzasz krok piąty, czyli wklejasz gotowy kod CSS do elementu HTML renderowanego na każdej podstronie aplikacji.

Dark Mode w Bubble – Podsumowanie

W mojej opinii metoda nadpisywania wartości zmiennych kolorystycznych jest dużo lepszym sposobem na wdrożenie dark mode w aplikacji Bubble niż tradycyjne podejście opierające się na wyrażeniach warunkowych. Umożliwia ona dodanie wygodnej z punktu widzenia użytkownika funkcji zmiany kolorystyki aplikacji stosunkowo niskim nakładem pracy programistycznej – niezależnie od tego jak bardzo złożony jest projekt, nad którym pracujemy.

Skontaktuj się
havenocode - cover image of an article about no-code development
Czy no-code low-code jest dla Twojej firmy? Poznaj wady i zalety LCNC w praktyce

Poznaj prawdę o no code low code i sprawdź, czy to technologia dla Ciebie i Twoich potrzeb. Zobacz jakie LCNC ma wady i zalety w biznesowej praktyce.

AUTOR
Marcin Gontarski
CZYTAJ WIĘCEJ
havenocode - cover image of an article about no-code development
Jak no-code low-code wspiera Project Management?

Czy technologia no-code low-code może wspierać zarządzanie? Jakie korzyści niesie dla Project Managerów? Wiele, sprawdź!

AUTOR
Marcin Gontarski
CZYTAJ WIĘCEJ
havenocode - cover image of an article about no-code development
Low-code vs. tradycyjne programowanie - jaką technologię wybrać?

Low-code czy może tradycyjny development? Które podejście będzie lepsze w procesie tworzenia oprogramowań? Sprawdź!

AUTOR
Marcin Gontarski
CZYTAJ WIĘCEJ
Hej!
Opowiedz mi o swoim pomyśle!
Odpowiemy w ciągu 24 godzin. Tak, to TAKIE proste!
Emil Bednarczyk, havenocode NoCode and LowCode Development Agency CEO and Client Partner
Emil Bednarczyk
Client Partner / havenocode.io
M: +48 792 015 688
Hej!
Opowiedz mi o swoim pomyśle!
Odpowiemy w ciągu 24 godzin. Tak, to TAKIE proste!
1
W jakich wyzwaniach możemy Ci pomóc?
2
Jaki jest Twój budżet?
3
Czy potrzebujesz NDA?
4
Podaj nam więcej szczegółów
Dziękujęmy! Twoja wiadomość została wysłana. Jeśli chcesz dowiedzieć sie więcej o no-code, zapraszamy na nasz blog!
Czytaj o no-code
Wystąpił błąd, formularz nie został wysłany.

Szukasz wartościowych artykułów na temat technologii no-code i low-code? Przeczytaj najnowsze artykuły o low code i no code na naszym blogu! Zobacz, jak tworzyć oprogramowanie, stawiać strony internetowe czy budować aplikacje mobilne bez kodowania.

Sprawdź eksperckie artykuły, w których poznasz najlepsze platformy low code i najlepsze platformy no code: Bubble, Webflow, Flutter Flow, Xano oraz wiele innych. Naucz się podstaw lub poznaj zaawansowane metody i zostań no-code developerem.

Nasz No Code Low Code Blog wprowadzi Cię do świata innowacyjnych technologii, w którym tworzenie oprogramowania jest proste i przyjemne. Jeśli chcesz stworzyć aplikację, zbudować MVP lub postawić stronę z no-code / low-code, to trafiłeś idealnie! Zyskaj wiedzę techniczną i biznesową z havenocode już teraz!