Breakpointy
Breakpointy v Design systému gov.cz
Breakpointy určují šířky, na kterých se mění rozvržení stránky. Design systém gov.cz je stavěný mobile first: výchozím stavem je nejužší zobrazení a každý breakpoint přidává pravidla směrem vzhůru.
Sada je záměrně malá — pět pásem pokryje telefon, tablet i desktop. Breakpoint navíc znamená další rozvržení, které je potřeba navrhnout, otestovat a udržovat.
Hodnoty
| Název | Hodnota | Šířka při 16px | Pásmo platnosti | Typické zařízení |
|---|---|---|---|---|
none | 0 | 0 px | 0 – 591 px | telefon portrait |
sm | 37em | 592 px | 592 – 767 px | telefon landscape / phablet |
md | 48em | 768 px | 768 – 991 px | tablet portrait |
lg | 62em | 992 px | 992 – 1279 px | tablet landscape / notebook |
xl | 80em | 1280 px | 1280 px a více | desktop |
Nad xl se rozvržení už nemění. Šířka obsahu je zastropovaná tokenem --templates-layout-page-limit-max (75rem = 1200 px), takže na širokých monitorech zůstává po stranách volné místo místo neúnosně dlouhých řádků textu.
Sadu nedoplňujeme o 2xl — nad xl by dnes nic neměnil.
Proč jsou hodnoty v em a ne v px
Breakpointy jsou definované v em, takže se vztahují k základní velikosti písma v prohlížeči. Když si čtenář text zvětší, layout se překlopí do užší varianty dřív — obsah se tedy přeskládá místo toho, aby se zvětšené písmo mačkalo do stejně široké mřížky. To je záměr a plní WCAG 1.4.4 Změna velikosti textu.
Praktický důsledek: hodnoty v px platí jen při výchozí velikosti písma 16 px. Všechny hodnoty jsou dělitelné šestnácti, aby jim v em odpovídala celá čísla.
Jak se breakpointy používají
Ve stylech přes mixin mq(), který se stará o správné hranice pásem:
@use "@gov-design-system-ce/core/src/sass/mixins" as mixin;
.example {
// Od `md` výš (min-width: 48em)
@include mixin.mq($from: md) {
display: flex;
}
// Pod `lg` (max-width: 61.99em) — horní hranice je nezahrnutá,
// takže pásma na sebe navazují bez mezery i bez přesahu.
@include mixin.mq($until: lg) {
display: block;
}
}V komponentách jsou breakpointy dostupné rovnou jako atributy a utility třídy:
gov-spacer—<gov-spacer size="l" breakpoint="md">přidá odsazení až od daného breakpointu.gov-grid—col-span-md,row-span-lga podobně.gov-hide--mdskryje prvek pod daným breakpointem.
V JavaScriptu nepoužívejte window.innerWidth — porovnává px proti em breakpointům, takže se při zvětšeném písmu rozejde se styly. Použijte hodnoty z balíčku @gov-design-system-ce/utils, které vyhodnotí stejný media dotaz, jaký generují styly:
import {matchesFrom, onBreakpointChange} from "@gov-design-system-ce/utils"
if (matchesFrom("lg")) {
// desktopová varianta
}
const unsubscribe = onBreakpointChange("lg", (matches) => {
// volá se jen při skutečném překlopení, ne na každý pixel při resize
})Container queries — jiná osa než breakpointy
Část komponent nereaguje na šířku okna, ale na šířku vlastního kontejneru. Karta v úzkém sloupci mřížky se tedy zalomí do mobilní varianty i na širokém monitoru. Takto se chovají gov-card, gov-tile, gov-empty a gov-error-code.
Názvy breakpointů jsou stejné, význam se ale liší: sm u container query znamená „kontejner je široký aspoň 592 px", ne „okno je široké aspoň 592 px".
Doporučené šířky pro návrh ve Figmě
Framy volte doprostřed pásma, ne na jeho hranu — na hraně se chování zlomu právě mění a návrh pak neukazuje ani jednu z variant spolehlivě.
| Frame | Pásmo | Reprezentuje |
|---|---|---|
| 390 px | none | telefon portrait |
| 680 px | sm | telefon landscape / phablet |
| 834 px | md | tablet portrait |
| 1150 px | lg | tablet landscape / notebook |
| 1440 px | xl | desktop |
Kromě toho je dobré ověřit dvě situace mimo tabulku: 320 px jako závazné minimum podle WCAG 1.4.10 Reflow (obsah musí fungovat bez vodorovného posuvníku), a 1920 px jako nejběžnější velký monitor — samostatný breakpoint pro něj nemáme, přesto se na něm layout nesmí rozpadnout do příliš dlouhých řádků.
Kde jsou breakpointy definované
Zdrojem pravdy je jediná mapa v packages/core/src/sass/variables/_mq.scss. Z ní vychází mixiny mq() a cq(), generované utility třídy i hodnoty pro JavaScript (packages/utils/lib/breakpoints.utils.ts). Soulad obou míst hlídá kontrola npm run breakpoints:check, takže se hodnoty nemohou rozejít.