Przewodnik po obsłudze CSS w przeglądarkach
Opublikowany: 2022-03-10Nigdy nie będziemy żyć w świecie, w którym wszyscy przeglądający nasze witryny mają identyczną przeglądarkę i wersję przeglądarki, tak jak nigdy nie będziemy żyć w świecie, w którym wszyscy mają ten sam rozmiar ekranu i rozdzielczość. Oznacza to, że zajmowanie się starymi przeglądarkami — lub przeglądarkami, które nie obsługują czegoś, z czego chcemy korzystać — jest częścią pracy programisty. To powiedziawszy, teraz jest znacznie lepiej niż w przeszłości, a w tym artykule przyjrzę się różnym typom problemów z obsługą przeglądarek, które możemy napotkać. Pokażę wam kilka sposobów radzenia sobie z nimi, a także przyjrzę się rzeczom, które mogą się wkrótce pojawić i które mogą pomóc.
Dlaczego mamy te różnice?
Nawet w świecie, w którym większość przeglądarek jest opartych na Chromium, nie wszystkie te przeglądarki korzystają z tej samej wersji Chromium, co Google Chrome. Oznacza to, że przeglądarka oparta na Chromium, taka jak Vivaldi, może znajdować się w kilku wersjach za Google Chrome.
I oczywiście użytkownicy nie zawsze szybko aktualizują swoje przeglądarki, chociaż sytuacja ta poprawiła się w ostatnich latach, a większość przeglądarek po cichu się aktualizuje.
Istnieje również sposób, w jaki nowe funkcje trafiają do przeglądarek. Nie jest tak, że nowe funkcje CSS są projektowane przez Grupę Roboczą CSS, a kompletna specyfikacja jest przekazywana dostawcom przeglądarek wraz z instrukcją ich implementacji. Dość często dopiero w przypadku eksperymentalnej implementacji można dopracować wszystkie najdrobniejsze szczegóły specyfikacji. Dlatego opracowywanie funkcji jest procesem iteracyjnym i wymaga, aby przeglądarki implementowały te specyfikacje w fazie rozwoju. Chociaż implementacja ma miejsce w dzisiejszych czasach najczęściej za flagą w przeglądarce lub jest dostępna tylko w wersji Nightly lub podglądu, gdy przeglądarka ma pełną funkcję, prawdopodobnie włączy ją dla wszystkich, nawet jeśli żadna inna przeglądarka jeszcze nie obsługuje.
Wszystko to oznacza, że — na ile nam się to podoba — nigdy nie będziemy istnieć w świecie, w którym funkcje są magicznie dostępne na każdym komputerze stacjonarnym i telefonie jednocześnie. Jeśli jesteś profesjonalnym programistą internetowym, Twoim zadaniem jest uporanie się z tym faktem.
Błędy a brak wsparcia
Mamy do czynienia z trzema problemami związanymi z obsługą przeglądarek:
- Brak obsługi funkcji
Pierwszym problemem (i najłatwiejszym do rozwiązania) jest sytuacja, gdy przeglądarka w ogóle nie obsługuje tej funkcji. - Radzenie sobie z „błędami” przeglądarki
Po drugie, przeglądarka twierdzi, że obsługuje tę funkcję, ale robi to w inny sposób niż inne przeglądarki obsługujące tę funkcję. Taki problem nazywamy „błędem przeglądarki”, ponieważ efektem końcowym jest niespójne zachowanie. - Częściowa obsługa właściwości CSS
Ten staje się coraz bardziej powszechny; sytuacja, w której przeglądarka obsługuje funkcję — ale tylko w jednym kontekście.
Dobrze jest zrozumieć, z czym masz do czynienia, gdy widzisz różnicę między przeglądarkami, więc przyjrzyjmy się po kolei każdemu z tych problemów.
1. Brak obsługi funkcji
Jeśli używasz właściwości lub wartości CSS, których przeglądarka nie rozumie, przeglądarka je zignoruje. Jest tak samo, niezależnie od tego, czy korzystasz z nieobsługiwanej funkcji, czy tworzysz funkcję i próbujesz jej użyć. Jeśli przeglądarka nie rozumie tej linii CSS, po prostu ją pomija i zajmuje się następną rzeczą, którą rozumie.
Ta zasada projektowania CSS oznacza, że możesz z radością korzystać z nowych funkcji, wiedząc, że nic złego nie stanie się z przeglądarką, która nie ma wsparcia. W przypadku niektórych CSS, używanych wyłącznie jako ulepszenie, to wszystko, co musisz zrobić. Skorzystaj z tej funkcji, upewnij się, że gdy ta funkcja jest niedostępna, wrażenia są nadal dobre i to wszystko. Takie podejście jest podstawową ideą progresywnego ulepszania, wykorzystującą tę funkcję platformy, która umożliwia bezpieczne korzystanie z nowych rzeczy w przeglądarkach, które ich nie rozumieją.
Jeśli chcesz sprawdzić, czy funkcja, z której korzystasz, jest obsługiwana przez przeglądarki, możesz zajrzeć na stronę internetową Can I Use. Innym dobrym miejscem do szukania szczegółowych informacji o wsparciu jest strona dla każdej właściwości CSS w MDN. Tamtejsze dane dotyczące obsługi przeglądarek wydają się być bardzo szczegółowe.
Nowy CSS rozumie stary CSS
W miarę opracowywania nowych funkcji CSS zwraca się uwagę na ich interakcję z istniejącym CSS. Na przykład w specyfikacji Grid i Flexbox szczegółowo opisano, w jaki sposób display: grid
i display: flex
radzą sobie ze scenariuszami, takimi jak sytuacja, w której element pływający staje się elementem siatki lub kontener multicol jest przekształcany w siatkę. Oznacza to, że pewne zachowania są ignorowane, co pomaga po prostu nadpisać CSS dla nieobsługującej przeglądarki. Te zastąpienia są szczegółowo opisane na stronie dla progresywnego ulepszania i układu siatki w MDN.
Wykrywanie wsparcia za pomocą zapytań o funkcje
Powyższa metoda działa tylko wtedy, gdy CSS, którego chcesz użyć, nie wymaga innych właściwości. Może zaistnieć potrzeba dodania dodatkowych właściwości do CSS dla starszych przeglądarek, które będą również interpretowane przez przeglądarki obsługujące tę funkcję.
Dobry przykład można znaleźć podczas korzystania z układu siatki. Podczas gdy element pływający, który staje się elementem siatki, traci wszystkie zachowania ruchome, prawdopodobnie jeśli próbujesz utworzyć zastępczy układ siatki z elementem pływającym, dodasz do elementów procentowe szerokości i prawdopodobnie marginesy.
.grid > .item { width: 23%; margin: 0 1%; }
Te szerokości i marginesy będą nadal obowiązywać, gdy pływający element jest elementem siatki. Szerokość staje się procentem toru siatki, a nie pełną szerokością kontenera; wówczas zostanie zastosowany dowolny margines, a także określona przez Ciebie luka.
.grid > .item { width: 23%; margin: 0 1%; } .grid { display: grid; grid-template-columns: 1fr 1fr 1fr 1fr; column-gap: 1%; }
Na szczęście istnieje funkcja wbudowana w CSS i zaimplementowana w nowoczesnych przeglądarkach, która pomaga nam poradzić sobie z tą sytuacją. Zapytania o funkcje pozwalają nam bezpośrednio zapytać przeglądarkę, co obsługuje, a następnie zareagować na odpowiedź. Podobnie jak Zapytanie o media — które testuje niektóre właściwości urządzenia lub ekranu — Zapytania o funkcje sprawdzają obsługę właściwości i wartości CSS.
Przetestuj wsparcie
Testowanie pod kątem wsparcia jest najprostszym przypadkiem, używamy @supports
, a następnie testujemy właściwość i wartość CSS. Treść wewnątrz zapytania o funkcję zostanie uruchomiona tylko wtedy, gdy przeglądarka odpowie true, tj. obsługuje daną funkcję.
Test na brak wsparcia
Możesz zapytać przeglądarkę, czy nie obsługuje jakiejś funkcji. W takim przypadku kod w zapytaniu o funkcję zostanie uruchomiony tylko wtedy, gdy przeglądarka wskaże, że nie ma obsługi.
@supports not (display: grid) { .item { /* CSS from browsers which do not support grid layout */ } }
Test na wiele rzeczy
Jeśli potrzebujesz obsługi więcej niż jednej właściwości, użyj and
.
@supports (display: grid) and (shape-outside: circle()){ .item { /* CSS from browsers which support grid and CSS shapes */ } }
Jeśli potrzebujesz wsparcia jednej lub drugiej nieruchomości, użyj or
.
@supports (display: grid) or (display: flex){ .item { /* CSS from browsers which support grid or flexbox */ } }
Wybór właściwości i wartości do przetestowania
Nie musisz testować dla każdej właściwości, której chcesz użyć — po prostu coś, co wskazywałoby na obsługę funkcji, których planujesz używać. Dlatego, jeśli chcesz użyć układu siatki, możesz przetestować display: grid
. W przyszłości (i gdy obsługa subgrid trafi do przeglądarek), być może będziesz musiał być bardziej szczegółowy i przetestować funkcjonalność subgrid. W takim przypadku należy przetestować pod kątem grid-template-columns: subgrid
, aby uzyskać prawdziwą odpowiedź tylko od tych przeglądarek, które zaimplementowały obsługę subgrid.
Jeśli teraz wrócimy do naszego przykładu z zmiennoprzecinkową rezerwą, możemy zobaczyć, jak zapytania funkcji rozwiążą to za nas. To, co musimy zrobić, to wysłać zapytanie do przeglądarki, aby dowiedzieć się, czy obsługuje ona układ siatki. Jeśli tak, możemy ustawić szerokość elementu z powrotem na auto
, a margines na 0
.
.grid > .item { width: 23%; margin: 0 1%; } @supports(display: grid) { .grid { display: grid; grid-template-columns: 1fr 1fr 1fr 1fr; column-gap: 1%; } .grid > .item { width: auto; margin: 0; } }
Zauważ, że chociaż umieściłem cały kod siatki w moim zapytaniu o funkcję, nie muszę tego robić. Jeśli przeglądarka nie rozumiałaby właściwości siatki, zignorowałaby je, aby mogły bezpiecznie znajdować się poza zapytaniem o funkcję. Elementy, które muszą znajdować się w zapytaniu o funkcję w tym przykładzie, to właściwości marginesu i szerokości, ponieważ są one potrzebne w starym kodzie przeglądarki, ale mogą być również stosowane przez przeglądarki obsługujące.
Obejmij kaskadę
Bardzo prostym sposobem oferowania rozwiązań zastępczych jest wykorzystanie faktu, że przeglądarki ignorują CSS, którego nie rozumieją, oraz faktu, że tam, gdzie wszystko inne ma taką samą szczegółowość, brana jest pod uwagę kolejność w źródłach pod kątem tego, który CSS jest stosowany do elementu .
Najpierw piszesz kod CSS dla przeglądarek, które nie obsługują tej funkcji. Następnie przetestuj obsługę właściwości, których chcesz użyć, jeśli przeglądarka potwierdzi, że obsługuje, nadpisz kod zastępczy nowym kodem.
Jest to prawie ta sama procedura, której możesz użyć podczas korzystania z zapytań o media do projektowania responsywnego, zgodnie z podejściem zorientowanym na urządzenia mobilne. W tym podejściu zaczynasz od układu dla mniejszych ekranów, a następnie dodajesz lub nadpisujesz elementy dla większych ekranów w miarę przechodzenia przez punkty przerwania.
Powyższy sposób pracy oznacza, że nie musisz się martwić o przeglądarki, które nie obsługują zapytań o funkcje. Jak widać z Czy mogę używać , Zapytania o funkcje mają naprawdę świetne wsparcie. Wyróżniające się przeglądarki, które ich nie obsługują, to dowolna wersja Internet Explorera.
Prawdopodobnie jednak nowa funkcja, której chcesz użyć, nie jest również obsługiwana w IE. Tak więc w chwili obecnej prawie zawsze zaczynasz od pisania CSS dla przeglądarek bez obsługi, a następnie testujesz za pomocą zapytania o funkcję. To zapytanie dotyczące funkcji powinno testować wsparcie .
- Przeglądarki obsługujące Zapytania o funkcje zwrócą wartość true, jeśli mają wsparcie, a zatem zostanie użyty kod wewnątrz zapytania, zastępując kod dla starszych przeglądarek.
- Jeśli przeglądarka obsługuje Zapytania o funkcje, ale nie testuje funkcji, zwróci false. Kod wewnątrz zapytania o funkcję zostanie zignorowany.
- Jeśli przeglądarka nie obsługuje zapytań o cechy, wszystko w bloku zapytań o cechy zostanie zignorowane, co oznacza, że przeglądarka, taka jak IE11, użyje twojego starego kodu przeglądarki, co jest prawdopodobnie dokładnie tym, czego chcesz!
2. Radzenie sobie z „błędami” przeglądarki
Drugi problem z obsługą przeglądarek na szczęście staje się coraz mniej powszechny. Jeśli przeczytasz „What We Wish For” (opublikowany pod koniec zeszłego roku), możesz zapoznać się z niektórymi z bardziej zaskakujących błędów przeglądarek z przeszłości. To powiedziawszy, każde oprogramowanie może zawierać błędy, przeglądarki nie są wyjątkiem. A jeśli dodamy do tego fakt, że ze względu na cykliczny charakter implementacji specyfikacji, czasami przeglądarka coś zaimplementowała, a potem specyfikacja się zmieniła, więc teraz muszą wydać aktualizację. Dopóki ta aktualizacja nie zostanie wydana, możemy znajdować się w sytuacji, w której przeglądarki robią ze sobą coś innego.
Zapytania o funkcje nie mogą nam pomóc, jeśli przeglądarka zgłasza, że coś obsługuje źle. Nie ma trybu, w którym przeglądarka może powiedzieć „ Tak, ale prawdopodobnie Ci się to nie spodoba ”. Kiedy pojawia się rzeczywisty błąd w zakresie współdziałania, to właśnie w takich sytuacjach może być konieczne zwiększenie kreatywności.
Jeśli uważasz, że widzisz błąd, pierwszą rzeczą do zrobienia jest potwierdzenie tego. Czasami, gdy wydaje nam się, że widzimy błędne zachowanie, a przeglądarki robią różne rzeczy, wina leży po naszej stronie. Być może użyliśmy jakiejś nieprawidłowej składni lub próbujemy nadać styl niepoprawnemu kodowi HTML. W takich przypadkach przeglądarka spróbuje coś zrobić; Jednak ponieważ nie używasz języków tak, jak zostały zaprojektowane, każda przeglądarka może sobie radzić w inny sposób. Szybkie sprawdzenie poprawności kodu HTML i CSS to doskonały pierwszy krok.
W tym momencie prawdopodobnie szybko przeszukam i zobaczę, czy mój problem został już szeroko zrozumiany. Istnieje kilka repozytoriów znanych problemów, np. Flexbugs i Gridbugs. Jednak nawet dobrze dobrane kilka słów kluczowych może spowodować pojawienie się postów lub artykułów na temat Stack Overflow, które obejmują dany temat i mogą pomóc obejść ten problem.
Ale powiedzmy, że tak naprawdę nie wiesz, co powoduje błąd, co sprawia, że znalezienie rozwiązania jest dość trudne. Następnym krokiem jest więc utworzenie skróconego przypadku testowego Twojego problemu, tj. usunięcie wszystkiego, co nieistotne, aby pomóc Ci dokładnie określić, co powoduje błąd. Jeśli uważasz, że masz błąd CSS, czy możesz usunąć dowolny JavaScript lub odtworzyć ten sam styl poza frameworkiem? Często używam CodePen, aby zebrać zmniejszony przypadek testowy czegoś, co widzę; ma to tę dodatkową zaletę, że daje mi kod w sposób, który mogę łatwo udostępnić komuś innemu, jeśli będę musiał o to zapytać.
W większości przypadków, po wyizolowaniu problemu, można wymyślić alternatywny sposób osiągnięcia pożądanego rezultatu. Przekonasz się, że ktoś inny wymyślił sprytne obejście lub możesz opublikować gdzieś, aby poprosić o sugestie.
Mając to na uwadze, jeśli uważasz, że masz błąd przeglądarki i nie możesz znaleźć nikogo innego mówiącego o tym samym problemie, całkiem możliwe, że znalazłeś coś nowego, co powinno zostać zgłoszone. Z całym nowym CSS, który pojawił się niedawno, czasami mogą pojawić się problemy, gdy ludzie zaczynają używać rzeczy w połączeniu z innymi częściami CSS.
Sprawdź ten post Lea Verou dotyczący zgłaszania takich problemów: „Pomóż społeczności! Zgłoś błędy przeglądarki!”. Artykuł zawiera również świetne wskazówki dotyczące tworzenia skróconego przypadku testowego.
3. Częściowa obsługa właściwości CSS
Trzeci rodzaj problemu stał się bardziej powszechny ze względu na sposób projektowania nowoczesnych specyfikacji CSS. Jeśli myślimy o układzie siatki i Flexbox, te specyfikacje używają zarówno właściwości, jak i wartości z poziomu 3 wyrównania pola, aby wykonać wyrównanie. Dlatego właściwości takie jak align-items
, justify-content
i column-gap
są określone do użycia zarówno w Grid i Flexbox, jak i w innych metodach układu.
Jednak w chwili pisania tego tekstu właściwości gap
działają w układzie siatki we wszystkich przeglądarkach obsługujących siatkę, a column-gap
działają w Multicol; jednak tylko Firefox zaimplementował te właściwości dla Flexbox.
Jeśli miałbym użyć marginesów, aby utworzyć zapas dla Flexbox, a następnie przetestować odstępy między column-gap
i usunąć marginesy, moje pola nie będą miały między nimi odstępu w przeglądarkach obsługujących odstępy między column-gap
w Grid lub multicol, więc mój odstęp między kolumnami będzie wynosił REMOVED.
@supports(column-gap: 20px) { .flex { margin: 0; /* almost everything supports column-gap so this will always remove the margins, even if we do not have gap support in flexbox. */ } }
Jest to obecne ograniczenie zapytań o funkcje. Nie mamy możliwości przetestowania obsługi funkcji w innej funkcji. W powyższej sytuacji chcę zapytać przeglądarkę: „Czy masz wsparcie dla przerwy między kolumnami w Flexboxie?” W ten sposób mogę uzyskać negatywną odpowiedź, dzięki czemu mogę skorzystać z mojej rezerwy.
Podobny problem występuje we właściwościach fragmentacji CSS break-before
, break-after
i break-inside
. Ponieważ mają one lepsze wsparcie podczas drukowania strony, przeglądarki często żądają wsparcia. Jeśli jednak testujesz obsługę w multicol, otrzymasz coś, co wygląda na fałszywe alarmy. Poruszyłem ten problem w Grupie Roboczej CSS, jednak nie jest to prosty problem do rozwiązania. Jeśli masz jakieś przemyślenia, dodaj je tam.
Testowanie pod kątem obsługi selektora
Obecnie zapytania dotyczące funkcji mogą testować tylko właściwości i wartości CSS. Inną rzeczą, którą możemy przetestować, jest obsługa nowszych selektorów, takich jak te z poziomu 4 specyfikacji selektorów. Za flagą w Firefox Nightly znajduje się uwaga wyjaśniająca, a także implementacja nowej funkcji zapytań o funkcje, która pozwoli to osiągnąć.
Jeśli odwiedzisz about:config
w przeglądarce Firefox i włączysz flagę layout.css.supports-selector.enabled
, możesz sprawdzić, czy obsługiwane są różne selektory. Składnia jest obecnie bardzo prosta, na przykład do testowania selektora : :has
:
@supports selector(:has){ .item { /* CSS for support of :has */ } }
Jest to specyfikacja w fazie rozwoju, jednak możesz zobaczyć, w jaki sposób dodawane są funkcje, które pomagają nam zarządzać stale obecnymi problemami z obsługą przeglądarek.
Dalsza lektura
Może to wydawać się frustrujące, gdy chcesz skorzystać z funkcji i odkryć, że nie jest ona obsługiwana przez jedną z głównych przeglądarek lub jeśli coś wygląda inaczej. Podsumowałem kilka praktycznych dalszych lektur, które mogą pomóc.
- „Using CSS Grid: Supporting Browsers Without Grid” Opcje radzenia sobie ze starszymi przeglądarkami i CSS Grid
- Strona referencyjna MDN „Zapytania o funkcje” dla zapytań dotyczących funkcji
- Przewodnik MDN „CSS Grid And Progressive Enhancement” dotyczący progresywnego ulepszania siatki
- Przewodnik „Backwards Compatibility Of Flexbox” MDN dotyczący obsługi Flexbox, w tym szczegóły starszych wdrożeń z prefiksami
- „Najpierw biblioteka wzorców” Jak zarządzać kodem awaryjnym za pomocą biblioteki wzorców