Display & Platform
Central Design System предоставляет реактивную информацию об экране (брейкпоинты, размеры вьюпорта, мобильный режим) и о платформе (браузер, ОС, тип устройства) через один composable — useDisplay. Брейкпоинты используются одинаково в JavaScript и в стилях (SCSS-миксины cds-breakpoint-*), поэтому адаптивная логика в скрипте и CSS совпадает.
Точки преломления (breakpoints)
| Брейкпоинт | Диапазон ширины (px) | Стартовая ширина | Колонки сетки |
|---|---|---|---|
xs | 0 … 671 | 0 | 4 |
sm | 672 … 1055 | 672 | 8 |
md | 1056 … 1311 | 1056 | 16 |
lg | 1312 … 1583 | 1312 | 16 |
xl | 1584 … ∞ | 1584 | 16 |
Источник значений один:
- JS —
defaultDisplayOptions.thresholds(src/composables/useDisplay/internal/useDisplay.constants.ts); - SCSS —
$grid-breakpoints(src/styles/utilities/grid/_config.scss).
В JavaScript — useDisplay
Composable useDisplay возвращает реактивное состояние экрана и платформы. Он работает «из коробки», если приложение инициализировано через createCds (он провайдит cds:display).
import { useDisplay } from '@central-design-system/components';
const display = useDisplay();
display.width.value; // текущая ширина вьюпорта, px
display.name.value; // 'xs' | 'sm' | 'md' | 'lg' | 'xl'
display.mobile.value; // true, если width < mobileBreakpoint (по умолчанию 'sm')Доступные флаги
| Флаг | Значение |
|---|---|
xs / sm / md / lg / xl | активен ровно один — текущий брейкпоинт |
smUp / mdUp / lgUp / xlUp | ширина ≥ стартовой ширины брейкпоинта («и выше») |
smDown / mdDown / lgDown / xlDown | брейкпоинт и всё, что ниже («и ниже») |
name | имя текущего брейкпоинта |
mobile | мобильный режим (по mobileBreakpoint) |
mobileBreakpoint | текущий порог мобильного режима |
width / height | размеры вьюпорта, px |
thresholds | текущая карта порогов |
platform | флаги платформы/браузера (см. Платформа) |
update() | принудительно пересчитать размеры и платформу |
Например, mdUp истинно при width ≥ 1056, а smDown — при width < 1056 (то есть охватывает диапазоны xs и sm).
Пример в компоненте
import { useDisplay } from '@central-design-system/components';
const { mobile, mdUp } = useDisplay();
defineRender(() => (
<div class={{ 'is-mobile': mobile.value }}>
{mdUp.value ? <DesktopLayout /> : <MobileLayout />}
</div>
));Мобильный режим на уровне пропсов
Компоненты, подмешивающие defineDisplayProps(), принимают пропсы mobile и mobileBreakpoint — ими можно переопределить порог мобильного режима локально:
<!-- Мобильный режим включится при ширине < 1056px (md), а не по глобальному 'sm' -->
<CdsSlideGroup mobile-breakpoint="md" />Переопределение порогов глобально
Пороги и mobileBreakpoint настраиваются при инициализации:
import { createCds } from '@central-design-system/components';
app.use(createCds({
display: {
mobileBreakpoint: 'md',
thresholds: { xs: 0, sm: 600, md: 960, lg: 1280, xl: 1920 }
}
}));Если вы меняете пороги в JS — синхронизируйте их и в SCSS (
$grid-breakpoints), иначе адаптивность в скрипте и стилях разойдётся.
В SCSS — миксины cds-breakpoint-*
Миксины подключаются из публичной точки входа:
@use '@central-design-system/components/styles/breakpoints' as breakpoint;В чистом Dart Sass (без бандлера) используйте pkg-схему и Node-импортер:
@use 'pkg:@central-design-system/components/styles/breakpoints' as breakpoint;.
cds-breakpoint-up($name) — «и выше»
.card {
display: none;
// применится при min-width: 1056px (md и выше)
@include breakpoint.cds-breakpoint-up(md) {
display: block;
}
}cds-breakpoint-down($name) — «и ниже»
.sidebar {
// применится при max-width: 1055.98px — то есть на sm и xs
@include breakpoint.cds-breakpoint-down(sm) {
display: none;
}
}cds-breakpoint-down('<name>') покрывает сам брейкпоинт и все, что ниже (верхняя граница — старт следующего брейкпоинта минус 0.02px). Для крупнейшего брейкпоинта (xl) media query не генерируется — «xl и ниже» это все ширины.
cds-breakpoint-between($lower, $upper) — диапазон
.banner {
// min-width: 672px и max-width: 1056px
@include breakpoint.cds-breakpoint-between(sm, md) {
padding: 16px;
}
}Оба миксина также принимают число вместо имени: cds-breakpoint-up(900px).
Прочие миксины и функции
cds-breakpoint($name)— алиасcds-breakpoint-up.cds-largest-breakpoint— media query для самого крупного брейкпоинта.breakpoint-next($name)/breakpoint-prev($name)— соседний брейкпоинт.is-smallest-breakpoint($name)— является ли$nameнаименьшим.largest-breakpoint-name()— имя самого крупного брейкпоинта.
Соответствие JS ↔ CSS
Флаги useDisplay и media query миксинов покрывают одинаковые диапазоны ширины — это позволяет писать согласованную адаптивную логику в скрипте и стилях.
JS (useDisplay) | SCSS-миксин | Диапазон ширины |
|---|---|---|
smUp | cds-breakpoint-up(sm) | ≥ 672 |
mdUp | cds-breakpoint-up(md) | ≥ 1056 |
lgUp | cds-breakpoint-up(lg) | ≥ 1312 |
xlUp | cds-breakpoint-up(xl) | ≥ 1584 |
smDown | cds-breakpoint-down(sm) | < 1056 |
mdDown | cds-breakpoint-down(md) | < 1312 |
lgDown | cds-breakpoint-down(lg) | < 1584 |
xlDown | cds-breakpoint-down(xl) | все ширины |
Важно (миграция с CDS 3). В CDS 3 семантика
cds-breakpoint-downв SCSS отличалась от JS:down('sm')означало «строго нижеsm» (толькоxs), тогда какsmDownв JS — «smи ниже». В CDS 4 CSS выровнен под JS:down('<name>')теперь всегда «<name>и ниже». Если вы переносите стили из CDS 3 — сдвиньте аргументdown()на один вниз (старыйdown('md')⇒ новыйdown('sm')). См. Migration Guide.
Платформа (platform)
useDisplay().platform — реактивный объект с флагами устройства, ОС и браузера. Определение основано на navigator.userAgent и поддержке касаний.
import { useDisplay } from '@central-design-system/components';
const { platform } = useDisplay();
if (platform.value.ios) {
// особое поведение для iOS
}
const isTouchDevice = platform.value.touch;Поля объекта platform
Все поля — boolean.
| Поле | Значение |
|---|---|
android | устройство на Android |
ios | устройство на iOS (iPhone / iPad / iPod) |
cordova | приложение работает в Cordova |
electron | приложение работает в Electron |
chrome | браузер Chrome |
edge | браузер Edge |
firefox | браузер Firefox |
opera | браузер Opera |
win | ОС Windows |
mac | ОС macOS |
linux | ОС Linux |
touch | устройство поддерживает касания |
ssr | значение вычислено на сервере (SSR) |
Пример: класс на корне приложения
import { useDisplay } from '@central-design-system/components';
const { platform } = useDisplay();
defineRender(() => (
<div
class={{
'platform--ios': platform.value.ios,
'platform--android': platform.value.android,
'platform--touch': platform.value.touch
}}
>
<slot />
</div>
));Осторожно с user-agent sniffing. Определение браузера/ОС по
userAgentненадёжно (строку можно подменить, а новые браузеры — не распознаться). Используйтеplatformдля прогрессивных улучшений (например, специфичные фиксы под iOS Safari), а не как единственное условие доступа к функциональности. Для фич-детекта предпочитайте проверку возможностей ('ontouchstart' in windowи т. п.).
SSR
При серверном рендеринге userAgent недоступен, поэтому platform.ssr === true, а остальные флаги — false. После гидрации значения можно пересчитать вызовом display.update() (пересчитывает и размеры, и платформу). Начальные размеры для SSR задаются вторым аргументом createDisplay(options, ssr) / опцией ssr в createCds.