Wróć do listy
  • technologie
  • programowanie

5 nowości w świecie CSS które usprawnią Twoją pracę już dziś

Bartłomiej
Bartłomiej, Front-End Developer, WordPress Developer
15 minut czytania • 17.06.2024
5 nowości w świecie CSS które usprawnią Twoją pracę już dziś

W ostatnich latach ruch w sieci w przeważającym stopniu przebiega z wykorzystaniem przeglądarek opartych o trzy podstawowe silniki (Blink, Gecko oraz WebKit). Tak zwane modern browsers są rozwijane i aktualizowane w modelu evergreen, bez konieczności “ręcznego” instalowania aktualizacji (najczęściej odbywa się to “w tle” podczas restartu programu). Oznacza to, że nowe funkcjonalności mogą być wypuszczane są z większą regularnością.

Dzięki temu ostatnie lata przyniosły wiele ekscytujących nowości w świecie CSS, z niektórymi właściwościami zdążyliśmy już dawno okrzepnąć. Nie wyobrażam sobie obecnie tworzenia layoutów bez flexbox, css grid, czy css variables. Niedawno jednak wsparcia doczekało się również wiele ciekawych konceptów opracowywanych przez CSS Working Group.

W tym artykule postaram się przybliżyć 5 nowości, które na pewno zagoszczą na stałe w zestawie narzędzi, którymi posługuje się na co dzień. Wszystkie opisane funkcjonalności są wspierane przez ostatnie wersje nowoczesnych przeglądarek internetowych.

Właściwości i wartości logiczne

Właściwości logiczne pozwalają uporządkować i uspójnić nomenklaturę i działania związane z wymiarami elementów oraz przepływem tekstu. Do tej pory używaliśmy właściwości  fizycznych odnoszących się do wymiarów fizycznych urządzenia. Właściwości i wartości logiczne odnoszą się do logicznych właściwości przeglądanych treści. Kluczowe słowa inline oraz block definiowane są poprzez wertykalny i horyzontalny kierunek przepływu tekstu. Dzięki temu w prostszy sposób możemy rozwiązać problemy związane na przykład ze zmianą kierunku tekstu. Przykładowo gdy przystosowujemy szablon z rynku anglojęzycznego do rynków arabskojęzycznego, lub japońskiego – dotychczas musieliśmy nadpisywać wiele właściwości żeby tekst pisany od prawej do lewej i jego położenie wyglądało poprawnie.  Dobrze obrazuje to poniższy przykład gdzie używając właściwości logicznych otrzymujemy ten sam efekt wizualny pisząc niemal dwukrotnie mniej kodu, bez potrzeby nadpisywania styli gdy zmienia się kierunek przepływu pisma.

Przykład zapisany z użyciem właściwości fizycznych:

Przykład zapisany z użyciem właściwości logicznych:

Pełna lista właściwości i własności które mają logiczne odpowiedniki znajdziesz tutaj: CSS logical properties and values

Dynamiczne jednostki

Każdy kto próbował ustawić wysokość jakiegoś elementu w taki sposób, aby zajmował całą wysokość widocznego ekranu na pewno zmierzył się z problemem na który w końcu mamy rozwiązanie. Użycie 100vh w takim przypadku nie było nigdy w pełni poprawnym rozwiązaniem, na urządzeniach mobilnych oznacza to 100% wysokości viewportu, włączamy w to pasek adresu oraz pozostałe elementu UI, które w większości przypadków podczas scrollowania się chowają lub pokazują.

Grafika obrazująca jednoski vw i hv.
Grafika obrazująca jednostki vh na urządzeniach mobilnych.

Nasz element zajmuje wtedy więcej miejsca niż byśmy chcieli. Na ratunek przychodzą nam nowe jednostki:

Grafika obrazująca 4 ekrany mobilne, na któych zaprezentowano jednostki svh, lvh oraz dvh.
  • Small Viewport – odpowiada wielkości viewportu gdy elementy UI przeglądarki są rozwinięte. Jednostki rozpoczynają się prefixem sv*:
    • svh – wysokość małego viewportu
    • svw – szerokość małego viewportu
    • svb – wysokość małego viewportu w znaczeniu logicznym
    • svi – szerokość małego viewportu w znaczeniu logicznym
    • svmin – przyjmuję mniejszą wartość spośród svh i svw
    • svmax – przyjmuje większą wartość spośród svh i svw
  • Large Viewport – odpowiada wielkości viewportu gdy elementy UI są niewidoczne. Jednostki są analogiczne do jednostek małego viewportu tylko z prefixem lv*
  • Dynamic Viewport – przyjmuje wartość małego lub dużego viewportu w zależności od tego czy elementy UI są widoczne w danej chwili czy nie. Jednostki są analogiczne do jednostek małego viewportu tylko z prefixem dv*

Warto pamiętać że domyślnie wirtualna klawiatura nie jest brana pod uwagę jako element UI, więc pojawienie się jej na ekranie nie spowoduje przeliczenia rozmiarów elementu dla którego użyto dynamiczne jednostki.

CSS Container Queries

Container Queries umożliwiają stylowanie elementów w zależności wymiarów zdefiniowanego kontenera. Do tej pory aby np. zmienić layout elementu w zależności od jego rozmiaru mogliśmy się posłużyć media queries gdzie zdefiniowaliśmy w obrębie jakiego rozmiaru viewportu element ma się zmienić. Dzięki container queries możemy zmieniać layout w zależności od szerokości elementu który stylujemy. W erze komponentów ta funkcjonalność może okazać się wielce przydatną. Na przykładzie poniżej widzimy identyczny element umieszczony w różnym kontekście, layout jest zmienny w zależności od szerokości poszczególnych elementów.

Aby użyć container query musimy utworzyć element który będzie kontenerem dla naszego elementu. Warto zauważyć że ten kontener nie może być stylizowany wewnątrz container query który się do niego odnosi. Definiujemy tutaj kontener oraz typ kontenera. Container queries odnoszące się do wymiarów elementu mogą mieć typ inline-size (szerokości elementu) lub size (szerokość i wysokość elementu). Istnieje również typ normal który będzie definiował kontener w zależności od innych właściwości elementu, tego typu queries nie mają jeszcze większego wsparcia w przeglądarkach dlatego nie będę w tym artykule rozwijał tego tematu.

<div class="card-outer">
    <div class="card">[...]</div>
</div>
.card-outer {
    container: card / inline-size;
    /* this is a shorthand
    container-type: inline-size;
    container-name: card;
    */
}

Mając tak zdefiniowany kontener możemy go używać w następujący sposób:

.card {
    ...
    /* styles when container width is wider than 768px */
    @container card (min-width: 768px) {
        ...
    }    
    /* styles when container width is wider than 992px */
    @container card (min-width: 768px) {
        ...
    }
}

Wraz z container queries pojawiły się nowe jednostki odnoszące się do wymiarów zdefiniowanego kontenera. Jednostki cqi | cqb | cqw | cqh | cqmin | cqmax odnoszą się do odpowiednio do szerokości logicznej | wysokości logicznej | szerokości | wysokości | mniejszej wartości z zakresu szerokości i wysokości | większej wartości z zakresu szerokości i wysokości.

/* New container query units refering to size of the container: cqi | cqb | cqw | cqh | cqmin | cqmax */
.card {
    dispaly: flex;
    gap: 5cqi; /* -> 5% inline size of container */
}

Pseudo-klasa :has()

Długo wyczekiwany feature dzięki któremu jesteśmy w stanie pisać style elementu nadrzędnego w zależności od wewnętrznych lub sąsiednich elementów. 

Bardzo częstym przypadkiem było customowe ostylowanie elementu input typu checkbox. Dotychczas przeważnie korzystaliśmy z kombinatora ‘+’ i ostylowywaliśmy element znajdujący się w bezpośrednim sąsiedztwie elementu input. Nie zawsze możemy jednak zmienić markup.

Z wykorzystaniem :has() jesteśmy w stanie zrobić to prościej. Zastosowanie tej pseudoklasy nie kończy się jednak na tym, myślę że użycie jej będzie powszechne i ułatwi nam rozwiązanie bardzo wielu problemów efektywniej.

Zobacz przykład poniżej:

CSS Cascade Layers

Koncept warstw jest rozszerzeniem kaskady css. Warstwy umiejscawiają się między szczegółowością selektorów (selector specificity), a stylami inline. Zaktualizowaną kaskadę CSS dobrze obrazuje poniższy obrazek:

Grafika obrazująca przebieg kaskady css.
źródło: https://css-tricks.com/css-cascade-layers/

Podstawowe założenia i zagadnienia związane z CSS Cascade Layers:

  • Priorytet warstw zależny jest od miejsca w którym zostały zdefiniowane, warto więc definiować warstwy na początku dokumentu.
  • Style bez zdefiniowanej warstwy mają wyższy priorytet niż style wewnątrz warstw.
  • Możemy importować cały arkusz styli do warstwy. Może okazać się to przydatne np. w przypadku konfliktu nazw warstw.
  • Możemy tworzyć wielopoziomowe warstwy.
  • Możemy tworzyć anonimowe warstwy – każda z takich warstw będzie unikalna, a jej kolejność będzie zależeć od miejsca użycia w dokumencie.
  • Słowo kluczowe revert-layer (jako wartość właściwości) pozwala na “cofnięcie” kaskady i użycie dowolnej wartości zdefiniowanej w poprzedniej warstwie.

Przykład użycia CSS Layers:

Ostrożnie z dyrektywą !important

Omawiając temat priorytetów należy wspomnieć o dyrektywie !important. W idealnym świecie nie powinniśmy musieć z niej korzystać, jednak dobrze wiemy jak się to ma do rzeczywistości. W kontekście warstw należy pamiętać że priorytet jest następujący:

Grafika obrazująca przebieg kaskady css - od najmniej znaczącej warstwy do najbardziej: pierwsza zdefiniowana warstwa, kolejne warstwy, ostatnia warstwa, style bez warstwy, style bez warstwy z dyrektywą !important, style ostatniej warstwy z dyrektywą !important, kolejne warstwy, style pierwszej zdefiniowanej warstwy z dyrektywą !important.

Taki priorytet jest analogiczny do znanego schematu w ramach pochodzenia stylów, gdzie priorytet dla przypomnienia jest jak na poniższym obrazku:

Grafika obrazująca przebieg kaskady css - od najmniej znaczącej warstwy do najbardziej: style przeglądarki, style użytkownika (preferencje użytkownika), style dokumentu, style dokumentu z dyrektywą !important, style użytkownika z dyrektywą !important, style przeglądarki z dyrektywą !important

Wprowadzenie warstw powinno w znacznym stopniu zmniejszyć potrzebę wykorzystywania dyrektywy !important, warto jednak pamiętać o rozkładzie priorytetów zaprezentowanym powyżej.

Tailwind i słowo kluczowe @layer

Jeśli korzystałeś kiedykolwiek z frameworku Tailwind to być może spotkałeś się już z konceptem warstw. W Tailwind możemy definiować style w ramach warstw base, components, utilities. Należy jednak pamiętać, że używając Tailwind te trzy warstwy nie będą kompilowane jako natywne warstwy CSS, a będą odnosić się do dyrektywy @tailwind za pomocą której “importujemy” style tailwind. Więcej o dyrektywach @tailwind i @layer we frameworku tailwind. Czytaj jak efektywnie poradzić sobie z CSS layers oraz dyrektywą @layer w tailwind.

Pozostałe nowości z których możesz korzystać już dziś o których warto wspomnieć

  • Native CSS nesting – natywne zagnieżdżanie w CSS (w przykładach w artykule wykorzystuję tą funkcjonalność)
  • pseudo-klasy :is(), :where()
  • CSS Masking
  • text-wrap: balance
  • funkcja color-mix
  • nowe gamy kolorów (lch, oklch, lab, oklab)
  • pseudo-klasy :user-valid i :user-invalid dla elementu input
  • subgrid – pozwala na użycie siatki wyznaczonej przez rodzica z display: grid
  • aspect-ratio – możliwość ustawienia dla elementu stałej proporcji szerokości do wysokości
  • text-underline-offset – odstęp między tekstem a podkreśleniem
  • accent-color – ustawienie akcentu kolorystycznego dla niektórych elementów UI takich jak input:checkbox, :radio
  • funkcje trygonometryczne
  • align-content dla elementów blokowych

Podsumowanie

CSS kontynuuje swoją ewolucję, opisane powyżej funkcjonalności przynoszą nam potężne narzędzia. Dzięki nim będziemy mogli w bardziej efektywny sposób organizować nasz kod co powinno wpłynąć zarówno na jakość naszych projektów jak i rozmiar plików CSS, a każdy bajt to jak wiemy cenny zasób.

Bibliografia i przydatne linki

Podobał Ci się ten artykuł? Udostępnij go!
Szukasz doświadczonego zespołu programistycznego? Porozmawiajmy o konkretach.
Skontaktuj się z nami
Marcin Stawowiak
Marcin Stawowiak
Co-founder, Executive Manager
Szukasz doświadczonego zespołu programistycznego?
Porozmawiajmy o konkretach.
Smultron Web Development
ul. Sławkowska 12
31-014 Kraków
NIP: 6762482785
Icon
 Oferta PDF						Oferta PDF Icon
 Napisz						Napisz Icon
 Zadzwoń						Zadzwoń Icon
 Projekty						Projekty