Kurs HTML i CSS · Moduł 9: Nowoczesny CSS

Nowoczesne funkcje CSS - część 2

6 min czytania
W tej lekcji4

Karuzela zdjęć, która zatrzymuje się dokładnie na kolejnym obrazie, formularz w barwach marki, jaśniejszy wariant złotego koloru na hover: jeszcze niedawno każde z tych zadań oznaczało bibliotekę JavaScript albo ręczne liczenie odcieni. W drugiej części naszej podróży po nowoczesnym CSS odkryjemy kolejne potężne narzędzia: scroll-snap, @supports, accent-color i color-mix(). Każde z nich rozwiązuje problem, który wcześniej wymagał JavaScriptu lub skomplikowanych obejść, tak jak odkrycia archeologów w Egipcie ujawniają coraz bardziej zaawansowane techniki starożytnych budowniczych.

Scroll Snap - przyciąganie podczas przewijania

Scroll Snap to mechanizm CSS, który pozwala tworzyć efekt przyciągania elementów do określonych punktów podczas przewijania. Dzięki niemu możesz stworzyć karuzele, galerie i sekcje full-page bez użycia JavaScriptu.

Wyobraź sobie korytarz w piramidzie z kolejnymi komorami: scroll-snap sprawia, że widok automatycznie zatrzymuje się na każdej komorze. Potrzebujesz dwóch właściwości: scroll-snap-type na kontenerze, który się przewija, i scroll-snap-align na jego dzieciach:

1/* Kontener z scroll-snap */
2.gallery {
3  display: flex;
4  overflow-x: auto;
5  scroll-snap-type: x mandatory;
6  /* mandatory - zawsze przyciąga do najbliższego punktu */
7  /* proximity - przyciąga tylko blisko punktu */
8  gap: 1rem;
9}
10
11/* Każdy element przyciąga do początku */
12.gallery-item {
13  scroll-snap-align: start;
14  /* Opcje: start, center, end */
15  flex-shrink: 0;
16  width: 300px;
17}
18
19/* Sekcje full-page z pionowym snap */
20.fullpage-container {
21  height: 100vh;
22  overflow-y: auto;
23  scroll-snap-type: y mandatory;
24}
25
26.fullpage-section {
27  height: 100vh;
28  scroll-snap-align: start;
29  display: flex;
30  align-items: center;
31  justify-content: center;
32}
33
34/* Scroll padding - offset dla fixed headers */
35.container {
36  scroll-snap-type: y mandatory;
37  scroll-padding-top: 80px;
38  /* Uwzględnia wysokość nagłówka */
39}

Zapis scroll-snap-type: x mandatory oznacza przewijanie w poziomie i obowiązkowe zatrzymanie na punkcie, a scroll-snap-align: start ustawia ten punkt na początku każdego elementu. Sam kontener musi się przewijać, dlatego ma overflow-x: auto. Polecam Ci proximity przy długich treściach bo mandatory zawsze wymusza zatrzymanie na punkcie, a przy długich lub nierównych sekcjach przeszkadza w swobodnym czytaniu.

@supports - wykrywanie możliwości przeglądarki

Reguła @supports (zwana też feature queries) pozwala sprawdzić, czy przeglądarka obsługuje daną właściwość CSS, zanim ją zastosujesz. To narzędzie do progressive enhancement, czyli budowania doświadczenia od podstaw i dodawania zaawansowanych funkcji tam, gdzie są dostępne.

To jak testowanie wytrzymałości materiału przed budową: starożytni Egipcjanie też sprawdzali kamień, zanim użyli go do budowy piramidy. Składnia to @supports, warunek w nawiasie i blok stylów:

1/* Podstawowe użycie @supports */
2.layout {
3  display: block; /* Fallback */
4}
5
6@supports (display: grid) {
7  .layout {
8    display: grid;
9    grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
10    gap: 1rem;
11  }
12}
13
14/* Sprawdzanie Container Queries */
15@supports (container-type: inline-size) {
16  .card-wrapper {
17    container-type: inline-size;
18  }
19
20  @container (min-width: 400px) {
21    .card {
22      flex-direction: row;
23    }
24  }
25}
26
27/* Negacja - jeśli NIE obsługuje */
28@supports not (aspect-ratio: 1 / 1) {
29  .square {
30    padding-top: 100%; /* Stary hack na proporcje */
31    height: 0;
32  }
33}
34
35/* Łączenie warunków */
36@supports (display: grid) and (gap: 1rem) {
37  .modern-grid {
38    display: grid;
39    gap: 1rem;
40  }
41}

Warunki łączysz słowami not, and i or, a funkcją selector() sprawdzisz nawet obsługę selektora, na przykład @supports selector(:has(a)). Przykład z aspect-ratio: 1 / 1 przypomina właściwość z części pierwszej, która wymusza proporcje, na przykład aspect-ratio: 16 / 9. Nowości wdrażaj zawsze w tej samej kolejności: sprawdź wsparcie na caniuse.com, napisz fallback, dodaj nowoczesną wersję w @supports i przetestuj w kilku przeglądarkach.

accent-color - stylowanie kontrolek formularza

Właściwość accent-color pozwala na zmianę koloru akcentu w natywnych kontrolkach formularza, takich jak checkboxy, radio buttony, range slidery i paski postępu. Wcześniej stylowanie tych elementów wymagało całkowitego nadpisania ich wyglądu, a teraz wystarczy jedna linia:

1/* Globalny kolor akcentu */
2:root {
3  accent-color: #d4af37; /* Złoty jak egipskie ozdoby */
4}
5
6/* Konkretne kontrolki */
7input[type="checkbox"] {
8  accent-color: #c9a66b;
9  width: 20px;
10  height: 20px;
11}
12
13input[type="radio"] {
14  accent-color: #1e3a5f;
15}
16
17input[type="range"] {
18  accent-color: #30d5c8;
19}
20
21progress {
22  accent-color: #d4af37;
23}
24
25/* Różne kolory dla różnych sekcji */
26.form-section--gold {
27  accent-color: gold;
28}
29
30.form-section--lapis {
31  accent-color: #1e3a5f;
32}

Właściwość jest dziedziczona, więc ustawiona na :root zmienia wszystkie kontrolki naraz, a sekcje mogą ją nadpisać. Przeglądarka sama dba o kontrast wewnątrz kontrolki, na przykład dobiera jasny lub ciemny znacznik w checkboksie. Na pola tekstowe i przyciski accent-color nie wpływa.

Masz więc drabinę możliwości, od najtrudniejszej do najłatwiejszej: własny checkbox od zera (ukryty natywny i pseudoelementy ::before oraz ::after), appearance: none z ręcznym stylowaniem, accent-color oraz color-scheme, który jednym słowem dopasowuje kontrolki do ciemnego motywu:

1/* Ciemny motyw dla całej strony, także kontrolek i pasków przewijania */
2:root {
3  color-scheme: dark;
4}
5
6/* Pełna kontrola: wyłączasz natywny wygląd i rysujesz własny */
7input[type="checkbox"].custom {
8  appearance: none;
9  width: 20px;
10  height: 20px;
11  border: 2px solid #d4af37;
12  border-radius: 4px;
13}

Po appearance: none checkbox traci natywny wygląd, także znacznik, więc stan zaznaczenia musisz narysować sam. Dlatego zaczynaj od accent-color i schodź niżej tylko wtedy, gdy projekt naprawdę tego wymaga.

color-mix() - mieszanie kolorów w CSS

Funkcja color-mix() pozwala na mieszanie dwóch kolorów w określonych proporcjach bezpośrednio w CSS. To potężne narzędzie do tworzenia wariantów kolorów, półprzezroczystych wersji i całych palet kolorystycznych.

Pomyśl o tym, jak starożytni Egipcjanie mieszali pigmenty: lazuryt z bielą dawał różne odcienie niebieskiego. color-mix() działa dokładnie tak samo. Podajesz przestrzeń kolorów, pierwszy kolor z procentem i drugi kolor:

1/* Podstawowa składnia */
2/* color-mix(in przestrzen-kolorow, kolor1 procent, kolor2) */
3
4/* Mieszanie w proporcjach */
5.lighter {
6  background: color-mix(in srgb, #d4af37 70%, white);
7  /* 70% złota + 30% białego */
8}
9
10.darker {
11  background: color-mix(in srgb, #d4af37 70%, black);
12  /* 70% złota + 30% czarnego */
13}
14
15/* Tworzenie semi-transparentnych wersji */
16.overlay {
17  background: color-mix(in srgb, #1e3a5f 50%, transparent);
18  /* 50% krycia */
19}
20
21/* Generowanie palety z jednego koloru bazowego */
22:root {
23  --brand: #d4af37;
24  --brand-light: color-mix(in srgb, var(--brand) 30%, white);
25  --brand-lighter: color-mix(in srgb, var(--brand) 15%, white);
26  --brand-dark: color-mix(in srgb, var(--brand) 70%, black);
27  --brand-darker: color-mix(in srgb, var(--brand) 50%, black);
28}
29
30/* Hover efekty */
31.button {
32  background: var(--brand);
33}
34
35.button:hover {
36  background: color-mix(in srgb, var(--brand) 85%, black);
37}
38
39/* Mieszanie w przestrzeni oklch (lepsze wyniki wizualne) */
40.gradient-step {
41  background: color-mix(in oklch, blue 60%, green);
42}

Zapis color-mix(in srgb, blue 70%, white) daje 70% niebieskiego i 30% bieli, czyli jaśniejszy niebieski, bo brakujący procent przypada drugiemu kolorowi. Mieszanie z transparent tworzy wersję półprzezroczystą, a przestrzeń oklch daje przejścia bardziej naturalne dla oka. Tak wygląda ewolucja kolorów w CSS: od nazw w rodzaju red, przez zapisy HEX i RGB, HSL i zmienne CSS, aż po mieszanie kolorów w przeglądarce.

Funkcja color-mix() w połączeniu ze zmiennymi CSS tworzy potężny system tematyzacji, w którym cała paleta kolorów powstaje z jednego koloru bazowego. Przypomnij sobie też narzędzia z poprzednich lekcji: :is() przejmuje specyficzność najsilniejszego selektora z listy, :where() ma zawsze specyficzność zero, a @property rejestruje typowane zmienne, które można animować. W piaskownicy poniżej przewiń galerię komnat, zmień kolor akcentu formularza i dopisz własny odcień do palety.

Pamiętaj: nowoczesny CSS to skrzynia z narzędziami mistrza budowniczego, ale każde nowe dłuto najpierw sprawdzasz przez @supports.

Kod do tej lekcji: index.html
1<!DOCTYPE html>
2<html lang="pl">
3<head>
4    <meta charset="UTF-8">
5    <meta name="viewport" content="width=device-width, initial-scale=1.0">
6    <title>Nowoczesne funkcje CSS - czesc 2</title>
7    <link rel="stylesheet" href="style.css">
8</head>
9<body>
10    <div class="page">
11        <h1>Nowoczesne funkcje CSS - czesc 2</h1>
12        <p class="subtitle">scroll-snap, @supports, accent-color, color-mix()</p>
13
14        <section>
15            <h2>Scroll Snap - galeria</h2>
16            <div class="snap-gallery">
17                <div class="snap-item" style="background:#d4af37">Komora 1</div>
18                <div class="snap-item" style="background:#8b6914">Komora 2</div>
19                <div class="snap-item" style="background:#c9a66b">Komora 3</div>
20                <div class="snap-item" style="background:#b87333">Komora 4</div>
21                <div class="snap-item" style="background:#1e3a5f">Komora 5</div>
22            </div>
23        </section>
24
25        <section>
26            <h2>@supports - Progressive Enhancement</h2>
27            <div class="supports-demo">
28                <div class="box">Element 1</div>
29                <div class="box">Element 2</div>
30                <div class="box">Element 3</div>
31            </div>
32        </section>
33
34        <section>
35            <h2>accent-color - Formularz</h2>
36            <form class="accent-form">
37                <label><input type="checkbox" checked> Opcja 1</label>
38                <label><input type="checkbox"> Opcja 2</label>
39                <label><input type="radio" name="r" checked> Radio A</label>
40                <label><input type="radio" name="r"> Radio B</label>
41                <label>Zakres: <input type="range" min="0" max="100" value="60"></label>
42                <label>Postep: <progress value="70" max="100">70%</progress></label>
43            </form>
44        </section>
45
46        <section>
47            <h2>color-mix() - Paleta kolorow</h2>
48            <div class="color-palette">
49                <div class="color-swatch swatch-lighter">Lighter</div>
50                <div class="color-swatch swatch-light">Light</div>
51                <div class="color-swatch swatch-base">Base</div>
52                <div class="color-swatch swatch-dark">Dark</div>
53                <div class="color-swatch swatch-darker">Darker</div>
54            </div>
55        </section>
56    </div>
57</body>
58</html>

Widzisz błąd w tej lekcji?

Sprawdź się

Odpowiedz na pytania z tej lekcji. Wybierz odpowiedź, a od razu zobaczysz, czy jest poprawna.

  1. 1. Jaka jest różnica między :is() a :where()?

  2. 2. Do czego służy scroll-snap-type w CSS?

To 2 z 8 pytań do tej lekcji. Pozostałe rozwiążesz w grze.

Zadania praktyczne w grze

  • Układanie w pionie

    Ułóż poprawną składnię zapytania @supports:

  • Klikanie w kolejności

    Ułóż składnię deklaracji scroll-snap-type:

  • Edytor kodu

    Zamień długą listę selektorów na :is(h1, h2, h3, h4) i użyj :where() dla low-specificity resets.

  • Edytor kodu

    Użyj scroll-snap-type: x mandatory i scroll-snap-align: start aby stworzyć galerię przyciągającą do itemów.

  • Edytor kodu

    Użyj color-mix(in srgb, var(--primary) 70%, white) aby tworzyć odcienie kolorów przez mieszanie.

  • Układanie w pionie

    Uporządkuj sposoby stylowania kontrolek formularza od najtrudniejszego do najłatwiejszego:

  • Edytor kodu

    Stwórz fallbacks używając @supports (display: grid), @supports (container-type: inline-size) dla progressive enhancement.

  • Układanie w pionie

    Uporządkuj sposoby definiowania kolorów w CSS od najstarszego do najnowszego:

  • Edytor kodu

    Użyj accent-color aby dostosować kolory checkbox, radio buttons, range sliders do brand colors.

  • Układanie w pionie

    Ułóż poprawną składnię deklaracji @property w CSS:

  • Układanie w poziomie

    Ułóż poprawną składnię funkcji color-mix():

  • Układanie w pionie

    Ułóż selektory CSS od najniższej do najwyższej specyficzności:

  • Układanie w pionie

    Ułóż poprawną składnię zagnieżdżonego @media w CSS Nesting:

  • Klikanie w kolejności

    Ułóż poprawną składnię ustawienia accent-color dla całej strony:

  • Klikanie w kolejności

    Ułóż składnię reguły @container:

  • Układanie w pionie

    Ułóż etapy wdrażania nowoczesnych funkcji CSS do projektu:

  • Układanie w pionie

    Ułóż poprawną składnię ustawienia proporcji obrazu na 16:9:

  • Układanie w pionie

    Ułóż etapy progressive enhancement od podstawowego do zaawansowanego:

  • Edytor kodu

    Zbuduj zaawansowany layout (sophisticated layout) zawierający: Container Queries dla responsive components, :has() dla conditional styling, CSS Nesting dla organized code, @layer dla cascade control, logical properties dla internationalization, clamp() dla fluid sizing, aspect-ratio dla media, :is/:where dla clean selectors, scroll-snap dla galleries, color-mix() dla theming, @supports dla fallbacks. Layout powinien reprezentować najnowocześniejszy egipski kompleks łączący starożytność z cutting-edge CSS!

Przydatne artykuły