Kreatywny kod słowny znak i ręce pisania na laptopie na tle międzynarodowej koncepcji rozwoju oprogramowania

Reguły @ w CSS (at-rules) – czy znasz je wszystkie?

13 min. czytania

Reguły @ (ang. at-rules) to elementy CSS, które „zaczynają się od małpki”, a potem… często przestajemy się nad nimi głębiej zastanawiać. Tymczasem od tego, jak korzystasz z @media, @font-face, @supports, @layer czy @container, zależy nie tylko utrzymanie kodu, ale też responsywność, wydajność i dostępność Twojej witryny.

Czym są reguły @ w CSS?

Reguły @ to specjalne instrukcje dla parsera CSS – mówią arkuszowi stylów, jak ma się zachowywać, zamiast stylować bezpośrednio konkretne elementy DOM.

Każda z nich:

  • zaczyna się od znaku @,
  • po którym następuje nazwa (np. media, font-face, supports),
  • i ma własną, odrębną składnię (część kończy się średnikiem, część otwiera blok {} z kolejnymi regułami).

Przykład (klasyczna reguła blokowa):

@media (min-width: 768px) {
.sidebar { display: block; }
}

Przykład (reguła zakończona średnikiem):

@import url("print.css") print;

Reguły @ służą m.in. do:

  • importowania innych arkuszy (@import),
  • deklarowania czcionek (@font-face),
  • tworzenia animacji (@keyframes),
  • kierowania części stylów do konkretnych mediów lub warunków (@media, @supports, @container),
  • zarządzania kaskadą (@layer),
  • definiowania własnych liczników i właściwości (@counter-style, @property).

Typy reguł @ – „jednoliniowe” i blokowe

Z punktu widzenia składni warto rozróżnić dwa główne typy:

Reguły „jednoliniowe” (zakończone średnikiem)

Do tej grupy należą:

  • reguła @charset,
  • reguła @import,
  • reguła @namespace.

Te reguły nie zawierają bloku {} – są pojedynczym poleceniem dla parsera.

Reguły blokowe (zawierają blok { … })

Najczęściej używane reguły blokowe to:

  • reguła @media,
  • reguła @supports,
  • reguła @container,
  • reguła @font-face,
  • reguła @keyframes,
  • reguła @counter-style,
  • reguła @page,
  • reguła @layer,
  • reguła @property,
  • reguła @scope.

To rozróżnienie ma znaczenie m.in. dlatego, że część reguł musi występować tylko na najwyższym poziomie arkusza (@charset, @import), a część można zagnieżdżać (np. @media wewnątrz @layer, @supports wewnątrz @media itd.).

Meta-reguły arkusza – @charset, @import, @namespace

@charset – deklaracja kodowania

@charset służy do określenia kodowania znaków używanego w pliku CSS.

Przykład:

@charset "UTF-8";

Musi być pierwszą rzeczą w pliku (bez spacji i komentarzy przed nią). W praktyce dziś częściej polega się na nagłówkach HTTP lub BOM, ale reguła wciąż istnieje i bywa spotykana.

Dostępność – zła interpretacja kodowania może prowadzić do błędnego wyświetlania treści (np. polskich znaków w generowanych content), co wpływa na zrozumiałość – zwłaszcza w alternatywnych widokach lub wydrukach.

@import – import innych arkuszy

@import pozwala wczytać inny arkusz CSS do bieżącego.

Przykład:

@import url("theme.css");
@import url("print.css") print;

Musi pojawiać się po @charset i przed zwykłymi regułami. Może też zawierać media query, dzięki czemu importujesz arkusz tylko dla określonych mediów.

Współcześnie odradza się nadużywanie @import ze względu na dodatkowe żądania HTTP i potencjalne opóźnienia w ładowaniu. Zamiast tego praktyczniejsze jest łączenie plików podczas budowania (bundling) lub umieszczanie <link> w HTML.

Dostępność – opóźnione ładowanie krytycznych stylów może negatywnie wpływać na stabilność layoutu (CLS) i powodować migotanie interfejsu, co utrudnia orientację użytkownikom korzystającym z powiększania, czytników ekranu lub z trudnościami poznawczymi.

@namespace – przestrzenie nazw XML

@namespace określa przestrzeń nazw XML używaną w arkuszu, np. dla dokumentów SVG lub XHTML.

Przykład:

@namespace svg "http://www.w3.org/2000/svg";
svg|circle { fill: red; }

W zwykłych stronach HTML reguła ta jest rzadko używana; przydaje się w zaawansowanych scenariuszach (np. stylowanie osadzonych dokumentów SVG).

Dostępność – poprawne stylowanie elementów SVG (np. ikon, diagramów) może ułatwić zapewnienie wystarczającego kontrastu czy wyraźniejszych wskaźników interakcji, co przekłada się na dostępność.

Zarządzanie kaskadą i architekturą CSS – @layer, @property

@layer – kontrola kolejności kaskady

@layer to reguła pozwalająca tworzyć warstwy kaskady CSS i ręcznie sterować, która warstwa ma priorytet.

Przykład:

@layer reset, base, components, utilities;

@layer reset {
* { box-sizing: border-box; }
}

@layer base {
body { font-family: system-ui, sans-serif; }
}

@layer components {
.btn { padding: .5rem 1rem; }
}

Deklaracja @layer reset, base, ... ustala kolejność warstw, a później możesz dodawać do nich reguły – ich wzajemne nadpisywanie jest deterministyczne, niezależnie od kolejności wystąpienia w pliku.

To ogromne wsparcie dla architektury CSS (np. rozdzielenie warstw: design system, komponenty, overrides).

Dostępność – lepsza kontrola nad kaskadą zmniejsza ryzyko przypadkowego nadpisania ważnych stylów (np. kontrastu, focusów). Możesz trzymać warstwę dostępności jako jedną z najwyższych i mieć pewność, że nie zostanie niechcący nadpisana niżej.

@property – własne właściwości CSS z typem (CSS Houdini)

@property pozwala zdefiniować własne właściwości CSS (custom properties) z walidacją typu, wartością domyślną i dziedziczeniem.

Przykład:

@property --brand-hue {
syntax: "<number>";
inherits: false;
initial-value: 210;
}

:root { --brand-hue: 210; }

.button {
background: hsl(var(--brand-hue) 80% 40%);
}

Najważniejsze parametry definicji to:

  • syntax – określa dozwolony typ (np. <color>, <length>, <number>);
  • inherits – informuje, czy właściwość dziedziczy;
  • initial-value – ustala domyślną wartość.

Dostępność – dobrze zdefiniowane custom properties ułatwiają np. tematy wysokiego kontrastu, tryb „low motion” czy dynamiczne zwiększanie odstępów – w jednym miejscu możesz zmienić wiele powiązanych stylów.

Responsywność i warunki – @media, @supports, @container, (historycznie) @viewport, @document

@media – media queries

@media pozwala stosować style tylko wtedy, gdy spełnione są określone warunki środowiska (typ urządzenia, szerokość okna, preferencje użytkownika itp.).

Przykład:

@media (min-width: 768px) {
.layout { display: grid; }
}

Od lat służy do responsywnego projektowania layoutu, ale rośnie znaczenie media features związanych z dostępnością. Kluczowe z nich to:

  • prefers-reduced-motion – użytkownik preferuje zredukowane animacje;
  • prefers-contrast – preferencja wyższego kontrastu;
  • prefers-color-scheme – tryb ciemny/jasny.

Przykład:

@media (prefers-reduced-motion: reduce) {
* {
scroll-behavior: auto;
animation-duration: 0.01ms !important;
animation-iteration-count: 1 !important;
transition-duration: 0.01ms !important;
}
}

Dostępność – właściwe użycie @media jest kluczowe dla responsywności z poszanowaniem preferencji użytkownika, a nie tylko rozmiaru ekranu.

@supports – feature queries

@supports testuje, czy przeglądarka obsługuje daną właściwość CSS (lub ich kombinację), i w zależności od tego stosuje określone reguły.

Przykład:

@supports (display: grid) {
.layout { display: grid; }
}

Możesz używać operatorów logicznych not, and, or:

@supports (display: grid) and (gap: 1rem) {
/* nowocześniejsza wersja layoutu */
}

Dostępność – dzięki @supports dostarczasz progresywne ulepszenia, zachowując prostszy, ale wciąż dostępny fallback (np. focusy przy braku wsparcia dla :focus-visible).

@container – container queries

@container umożliwia stosowanie stylów na podstawie rozmiarów (lub stylów) konkretnego kontenera, a nie całego viewportu.

Przykład:

.card-grid { container-type: inline-size; }

@container (min-width: 40rem) {
.card {
display: grid;
grid-template-columns: 1fr 2fr;
}
}

Jak z tym pracować efektywnie:

  • najpierw oznaczasz element jako kontener (przez container-type lub container),
  • potem tworzysz reguły @container, które reagują na rozmiar właśnie tego kontenera,
  • to ogromny krok naprzód względem klasycznych media queries – projektujesz komponenty, a nie „szerokości okna”.

Dostępność – bardziej elastyczne komponenty nie „rozsypują się” przy nietypowych powiększeniach, zoomie, w widoku split-screen lub na urządzeniach pomocniczych, co szczególnie pomaga przy powiększeniu 200–400%.

@viewport – historyczne podejście do meta viewport

Istniała reguła @viewport, pozwalająca przenieść część konfiguracji z <meta name="viewport"> do CSS.

Przykład:

@viewport {
width: device-width;
zoom: 1.0;
}

W praktyce wsparcie było niespójne i dziś jest to rozwiązanie przestarzałe / niezalecane (często tylko w wersjach prefiksowanych, np. @-ms-viewport). W nowoczesnych projektach stosujemy raczej meta viewport w HTML.

Dostępność – przewidywalne zachowanie viewportu jest kluczowe dla powiększania i skalowania, dlatego warto opierać się na szeroko wspieranym <meta name="viewport">.

@document – reguły zależne od adresu URL (niestandardowe)

@document stosuje style warunkowo na podstawie adresu dokumentu – np. tylko dla konkretnych domen lub ścieżek.

Przykład:

@document url("https://example.com/") {
body { background: yellow; }
}

W praktyce to niestandardowa reguła (eksperymentalna, głównie w Firefox), a specyfikacje zniechęcają do jej użycia w produkcji.

Dostępność – ograniczone i niepewne wsparcie czyni ją ryzykowną w kontekście spójnego doświadczenia między przeglądarkami.

Czcionki i typografia – @font-face, @font-feature-values, @font-palette-values, @counter-style

@font-face – wczytywanie własnych fontów

@font-face umożliwia zdefiniowanie niestandardowych fontów sieciowych, które będą pobierane przez przeglądarkę.

Przykład:

@font-face {
font-family: "MyAccessibleSans";
src: url("MyAccessibleSans.woff2") format("woff2");
font-display: swap;
}

Najważniejsze aspekty konfiguracji:

  • font-family – nazwa używana później w deklaracjach, np. font-family: "MyAccessibleSans", system-ui, sans-serif;;
  • src – lista źródeł i formatów (np. .woff2, .woff);
  • font-display – strategia wyświetlania (np. swap, fallback).

Dostępność

  • stosuj font-display: swap lub podobne, aby uniknąć długiego „niewidocznego” tekstu (FOIT),
  • wybieraj kroje zapewniające dobrą czytelność (kształty liter, odstępy),
  • zawsze zapewniaj sensowny fallback (system-ui, sans-serif) na wypadek problemów z ładowaniem.

@font-feature-values i zagnieżdżone reguły OpenType

@font-feature-values pozwala tworzyć nazwane zestawy funkcji OpenType, które potem możesz łatwo stosować w CSS.

Przykład:

@font-feature-values "MyAccessibleSans" {
@styleset {
friendly-ligatures: 1;
}
}

.body-text {
font-family: "MyAccessibleSans", system-ui, sans-serif;
font-feature-settings: "friendly-ligatures";
}

Wewnątrz występują dodatkowe „wewnętrzne” at-rules, m.in.: @stylistic, @styleset, @swash, @ornaments, @annotation, @character-variant.

Dostępność – niektóre funkcje OpenType (np. alternatywne cyfry czy warianty tablicowe) mogą poprawiać czytelność; nie narzucaj jednak ozdobnych form kosztem czytelności i pozwól je w razie potrzeby wyłączyć.

@font-palette-values – palety kolorów w fontach kolorowych

@font-palette-values pozwala wpływać na palety kolorów w czcionkach typu COLR/CPAL – dostępne m.in. w nowoczesnych fontach emoji i ikonograficznych.

Przykład:

@font-palette-values my-high-contrast {
font-family: "MyColorFont";
base-palette: 2;
}

Dostępność – możesz oferować wysokokontrastowe warianty ikon i emoji, reagując np. na prefers-contrast lub motyw użytkownika.

@counter-style – własne style numerowania list

@counter-style pozwala zdefiniować własny system numeracji list – zamiast standardowego decimal, disc itd.

Przykład:

@counter-style steps {
system: fixed;
symbols: "Krok 1" "Krok 2" "Krok 3";
suffix: ": ";
}

ol.steps { list-style: steps; }

Dostępność – własne style numerowania pomagają tworzyć bardziej opisowe listy, ale nie opieraj się wyłącznie na ozdobnej numeracji; czytniki ekranu interpretują listy strukturalnie, więc numeracja musi pozostać logiczna i przewidywalna.

Animacje i początkowe stany – @keyframes, @starting-style

@keyframes – klatki kluczowe animacji

@keyframes definiuje kluczowe stany animacji i właściwości zmieniające się w czasie.

Przykład:

@keyframes fade-in {
from { opacity: 0; }
to { opacity: 1; }
}

.modal {
animation: fade-in 250ms ease-out;
}

Możesz używać procentów (0%, 50%, 100%) lub słów kluczowych from, to; przeglądarka interpoluje wartości między tymi stanami.

Dostępność – szanuj prefers-reduced-motion i unikaj gwałtownych, migających animacji na dużych obszarach, by nie wywoływać dyskomfortu.

@starting-style – stan początkowy przed pierwszą zmianą stylu

@starting-style umożliwia zdefiniowanie początkowego stanu elementu przed pierwszą zmianą stylu – szczególnie przydatne przy animowaniu wejścia/wyjścia komponentów.

Przykład:

@starting-style {
.dialog[open] {
opacity: 0;
transform: translateY(1rem);
}
}

.dialog[open] {
opacity: 1;
transform: translateY(0);
transition: opacity 0.2s ease, transform 0.2s ease;
}

Dostępność – elementy powinny pojawiać się w sposób przewidywalny i bez „przeskoków”, co ułatwia orientację przestrzenną.

Strony do druku i publikacje – @page i reguły brzegów

@page – stylowanie stron wydruku

@page pozwala modyfikować rozmiar strony, orientację i marginesy dla kontekstu druku (print).

Przykład:

@page {
size: A4 portrait;
margin: 2cm;
}

@media print {
body { font-size: 12pt; }
}

Możesz też stosować pseudoklasy stron, aby inaczej stylować pierwszą stronę, parzyste/nieparzyste itp.

Dostępność – dla wielu użytkowników dostępność oznacza także czytelny wydruk; dzięki @page i @media print możesz usunąć zbędne elementy, zwiększyć rozmiar fontu, poprawić kontrast i zachować strukturę nagłówków.

Struktura dokumentu i selektory przyszłości – @scope

@scope – zasięg dla selektorów

@scope pozwala ograniczyć zasięg selektorów do konkretnego poddrzewa DOM.

Przykład:

@scope (.article) {
h2 { font-size: 1.5rem; }
.note { border-left: 4px solid var(--accent); }
}

W tym przykładzie:

  • wewnątrz @scope (.article) stylujesz tylko h2 i .note wewnątrz elementów .article,
  • unikasz nadmiernie specyficznych selektorów typu .article h2,
  • zmniejszasz ryzyko „przecieków” stylów w innych częściach strony.

Dostępność – lepsza struktura i separacja stylów sprzyjają konsekwencji interfejsu, co ułatwia budowanie przewidywalnego doświadczenia użytkownika.

Mniej znane / specjalistyczne reguły – niestandardowe reguły @ (Houdini) i reguły specyficzne dla dostawców

Niestandardowe reguły @ w CSS Houdini

Nowoczesne API CSS (Houdini) umożliwiają definiowanie własnych reguł @ po stronie JavaScript, które następnie są rozumiane przez parser CSSOM.

To obszar raczej eksperymentalny – używany głównie w zaawansowanych bibliotekach i narzędziach, niż w zwykłych projektach produkcyjnych. Przykładowe zastosowania to własne systemy tematyzowania oraz specyficzne dla projektu dialekty CSS kompilowane po stronie klienta.

Dostępność – jeżeli używasz niestandardowych at-rules, upewnij się, że istnieje bezpieczny fallback, a podstawowa wersja interfejsu (bez Houdini) pozostaje funkcjonalna i dostępna.

Jak reguły @ wpływają na dostępność – praktyczne wskazówki

Zbierając wszystko w całość, oto jak wykorzystać reguły @ z korzyścią dla dostępności:

  • projektuj mobilnie i responsywnie z myślą o preferencjach – użyj @media (prefers-reduced-motion: reduce) dla osób wrażliwych na ruch oraz @media (prefers-color-scheme: dark) w połączeniu z @property do przełączania motywów;
  • zadbaj o czytelne czcionki i przewidywalne ładowanie tekstu – w @font-face ustaw font-display: swap i sensowne fallbacki; unikaj zbyt ozdobnych funkcji OpenType bez możliwości wyłączenia;
  • buduj architekturę CSS sprzyjającą utrzymaniu dostępności – z @layer trzymaj focusy, kontrast i stany w wysokiej warstwie; używaj @scope, by unikać przypadkowego nadpisywania ważnych stylów;
  • stosuj progressive enhancement z @supports i @media – nowoczesne rozwiązania (Grid, container queries) nie mogą blokować działania prostszego, ale poprawnego fallbacku;
  • pamiętaj o druku i trybach offline – z @page i @media print przygotuj czytelne wydruki.

Słownik najważniejszych reguł @ (z perspektywy praktyka)

Poniżej znajdziesz skrócone zestawienie reguł @ oraz ich głównych zastosowań:

Reguła @ Główne zastosowanie
@charset Deklaracja kodowania pliku CSS.
@import Import innych arkuszy CSS.
@namespace Przestrzenie nazw XML (XHTML, SVG).
@media Media queries – responsywność, preferencje użytkownika.
@supports Feature queries – stylowanie zależne od wsparcia przez przeglądarkę.
@container Container queries – responsywne komponenty.
@layer Warstwy kaskady – kontrola kolejności nadpisywania.
@font-face Wczytywanie niestandardowych fontów.
@font-feature-values Nazwane zestawy funkcji OpenType i wewnętrzne at-rules.
@font-palette-values Konfiguracja palet kolorów w fontach kolorowych.
@counter-style Własne style numerowania list.
@keyframes Definiowanie animacji (klatek kluczowych).
@page Stylowanie stron wydruku (rozmiar, marginesy).
@property Typowane własne właściwości CSS (Houdini).
@scope Ograniczanie zasięgu selektorów do poddrzewa DOM.
@starting-style Definicja stylu początkowego przed pierwszą zmianą.
@viewport Historyczne, dziś niezalecane sterowanie viewportem CSS.
@document Niestandardowe style warunkowe oparte na adresie URL.