Изучите Porsche Design System v4: гибкие отступы, цветовые схемы CSS, типографика Porsche Next и конфигуратор с двумя вариантами. В примере приведены реальные выражения токенов и полный файл входа Vite с актуальными событиями сегментированного элемента управления.
Самостоятельная офлайн-интерпретация ролей токенов v4 и поведения сегментированного выбора для HTML/CSS. Без нативной среды выполнения PDS, удалённых шрифтов, официальных изображений моделей и реальных данных об автомобилях. · Справочник по реализации
02
Дизайн-система Porsche Справочник
Документация Porsche Design System v4; на страницах с токенами указана версия v4.8.0. Это справочник для определённой версии, а не заявление об актуальности последнего выпуска. Образцы цветов отделки созданы для приложения и не являются официальными кодами красок Porsche.
Дизайн-система Porsche Используйте основу v4 как целостный набор
Глобальные переменные теперь обязательны
В версии 4 стили компонентов строятся на глобальных переменных CSS. Поэтому подключение глобальной таблицы стилей — архитектурное требование, а не просто декоративный сброс стилей. В тот же файл входят нормализация и определения шрифта Porsche Next через font-face.
В этом справочнике собраны воедино требования v4 к компонентам и токенам. Не переносите примеры старых версий с обёртками текстовых полей или свойствами темы отдельных компонентов без сверки с руководством по миграции. Сама документация имеет версионность, поэтому в этой статье указана область применения, а не делается заявление о неизменности API.
Дизайн-система Porsche Цветовая схема выбирает полные пары ролей
Разделяйте роли интерфейса и образцы отделки
Токены фона, поверхности и основного цвета текста содержат пары light-dark(). Свойство CSS color-scheme выбирает нужный вариант. Укажите light, dark или light dark в зависимости от того, фиксирует ли приложение режим или следует предпочтениям пользователя.
Цвета отделки в этом примере — независимые авторские образцы. При переключении интерфейса в тёмный режим меняются окружающие поверхности и текст, но не выбранная отделка. Роли цветов с пониженной контрастностью предназначены для декора; использовать их для обязательной подписи варианта нельзя — это выходит за рамки назначения токена.
Дизайн-система Porsche Гибкий ритм сочетается с фиксированными промежутками элементов управления
Используйте выражения clamp, если пространство должно увеличиваться
В Porsche предусмотрены статическая и гибкая шкалы. В нативном примере для отступов страницы используется среднее гибкое выражение, а промежутки 16px и 32px задают стабильные интервалы внутри области параметров. Ограничение максимальной величины интервала не даёт пустому пространству бесконечно расти на широких экранах.
При ширине менее 760px, одном из задокументированных значений контрольной точки, пример меняет широкую компоновку с визуальным блоком и элементами управления на вертикальную последовательность разделов. Решение использовать вертикальную компоновку относится к приложению; само значение контрольной точки взято из справочника системы.
Дизайн-система Porsche Типографика зависит от предоставленного шрифта
Выражение высоты строки — не универсальный коэффициент
Для Porsche Next задокументирован набор резервных шрифтов и шкала размеров с фиксированными малыми и гибкими крупными значениями. leadingNormal использует единицы ex, зависящие от высоты строчной буквы в шрифте, а также фиксированную добавку в пикселях. Замена этого значения произвольным коэффициентом 1.5 меняет задуманную ритмику.
В офлайн-интерпретации используется локальный резервный шрифт и комфортная высота строки, а не создаётся видимость, будто лицензированный шрифт включён в комплект. В нативном примере фактическое начертание шрифта задаётся глобальной таблицей стилей. В типографике v4 для заголовков используется обычное начертание: для создания иерархии крупному тексту не обязательно быть жирным.
Дизайн-система Porsche Для элементов управления и контейнеров используются разные радиусы
Основную иерархию задают значения 12 и 24 пикселя
Стандартный радиус интерактивных элементов — 12px; для карточек и диалоговых окон используется 24px. Для компактных элементов управления радиус уменьшается до 8px, а для уведомлений составляет 16px. Если скруглить все элементы по максимальному радиусу, эти различия исчезнут.
В исходном примере автомобиля на широком фоне с радиусом 24px элементы управления скруглены на 12px. Силуэт автомобиля — оригинальная иллюстрация CSS, а не изображение модели Porsche или фотография продукта. Эту композицию можно использовать для выбора материалов, не создавая впечатления, что доступна реальная конфигурация.
Дизайн-система Porsche Сегментированный переключатель — это выбор, а не панель вкладок
Используйте стабильные значения и единый источник состояния
Каждый p-segmented-control-item задаёт значение. Событие change возвращает это значение в event.detail, и пример сохраняет его перед обновлением сводки. Группа имеет видимую метку, благодаря чему варианты отделки и колёс остаются различимыми.
В версии 4 API поддерживается адаптивное количество столбцов и, при необходимости, прокрутка без переноса. Короткие варианты могут отображаться одновременно; длинные локализованные метки следует переносить или показывать в специально предусмотренной прокручиваемой области, а не обрезать. Отключённые элементы управления не попадают в данные формы — это важно учитывать, если дорабатывать пример до полноценной формы.
Инициализируйте значения отделки и колёс один раз в состоянии приложения.
Получайте detail.value из события change группы.
Одновременно обновляйте наглядный пример и текстовое описание выбора.
При изменении выбора очищайте ранее сохранённую сводку.
Дизайн-система Porsche Локальный выбор — это не завершённая транзакция
Явно указывайте тип кнопки
По умолчанию p-button отправляет форму. В примере задано type="button", поскольку сохранение комбинации и смена цветовой схемы — локальные действия. Для переходов используйте компонент Link, а не кнопку с вымышленным адресом.
Основное действие точно сообщает о произошедшем: комбинация сохранена для текущего сеанса на странице. Оно не подразумевает сохранения после перезагрузки, записи в аккаунт или оформления заказа. Такое ограниченное поведение намеренно выбрано и полностью подходит для демонстрационного интерфейса.
Основное действие сохраняет текущую комбинацию локально.
Вторичное действие меняет цветовую схему интерфейса.
Для обоих действий сохраняются видимые подписи.
Индикатор загрузки не отображается, если ожидающей операции нет.
Дизайн-система Porsche Загружайте компоненты и предотвращайте сбои при первом отображении
Загрузчик, таблица стилей и компилятор работают вместе
В конфигурации Vite официальный фрагмент загрузчика внедряется в тело документа. Главный файл входа импортирует глобальную таблицу стилей и отображает настоящие пользовательские элементы. Правила :not(:defined) с ограниченной областью действия не дают выбранным тегам компонентов мигать до их регистрации.
В документированной конфигурации Vite отключено преобразование LightDark в Lightning CSS: указанный полифил считается неисправным. Важно сохранить это исключение: некорректная компиляция функции токена может нарушить работу темы, даже если разметка компонентов правильна. Позже можно добавить рекомендуемые предварительные загрузки с помощью документированных фрагментов для шрифтов, значков и компонентов.
Сохраните весь документ как index.html и откройте его в браузере. Независимая офлайн-интерпретация HTML/CSS ролей токенов и поведения сегментированного выбора в версии 4. Без нативной среды выполнения PDS, удалённых шрифтов, официальных изображений моделей и реальных данных об автомобилях.
html
<!doctype html><html lang="en"><meta charset="utf-8"><meta name="viewport" content="width=device-width"><title>Original finish study</title><style>:root{color-scheme:light;--canvas:#fff;--surface:hsl(240 10% 95%);--ink:hsl(225 66.7% 1.2%);--line:#c8c8cd;--paint:#b9b6ae}*{box-sizing:border-box}body{margin:0;background:var(--canvas);color:var(--ink);font:16px/1.5 'Arial Narrow',Arial,sans-serif}body.dark{color-scheme:dark;--canvas:hsl(225 66.7% 1.2%);--surface:hsl(240 2% 10%);--ink:#fcfcff;--line:#515156}button{font:inherit;cursor:pointer}button:focus-visible,input:focus-visible+span{outline:3px solid #1a44ea;outline-offset:4px}header{display:flex;justify-content:space-between;gap:16px;align-items:center;padding:24px 32px;border-bottom:1px solid var(--line)}header b{letter-spacing:3px;font-weight:400}header button{border:1px solid var(--line);color:var(--ink);background:var(--canvas);border-radius:12px;padding:8px 16px}main{max-width:1200px;padding:clamp(16px,1.25vw + 12px,36px);margin:auto}h1{font-size:clamp(1.6rem,1.56vw + 1.29rem,3.16rem);font-weight:400;line-height:1.2;margin:16px 0}.intro{color:var(--ink);opacity:.8;max-width:650px}.layout{display:grid;grid-template-columns:1.4fr 1fr;gap:32px;margin-top:32px}.stage{background:var(--surface);border-radius:24px;display:flex;flex-direction:column;justify-content:center;min-height:360px;overflow:hidden;padding:32px;position:relative}.scene{height:210px;position:relative;width:100%;max-width:520px;margin:auto}.car{height:80px;width:94%;position:absolute;bottom:28px;left:3%;background:var(--paint);border-radius:60% 35% 18% 22% / 75% 65% 25% 35%;box-shadow:inset 0 5px 10px #ffffff70,inset 0 -10px 12px #0003}.roof{position:absolute;bottom:80px;left:25%;width:46%;height:70px;background:var(--paint);border-radius:65% 55% 0 0;transform:skewX(-9deg)}.window{position:absolute;inset:9px 13px 4px;background:linear-gradient(135deg,#202d37,#67737b);border-radius:70% 52% 0 0;border-right:7px solid var(--paint)}.window:after{content:'';position:absolute;left:46%;top:0;height:100%;width:6px;background:var(--paint)}.wheel{position:absolute;bottom:12px;width:69px;height:69px;background:repeating-conic-gradient(#d2d5d8 0deg 13deg,#42464b 13deg 60deg);border:11px solid #191a1d;border-radius:50%;box-shadow:0 0 0 4px #08090a}.wheel.a{left:16%}.wheel.b{right:12%}.aero .wheel{background:radial-gradient(circle,#505860 0 18%,#c6c9cc 20% 65%,#464a4d 68%)}.headlight{position:absolute;right:0;top:18px;width:34px;height:12px;background:#fff9d8;border:2px solid #ffffff80;border-radius:80%;transform:rotate(15deg)}.shadow{height:10px;background:#0002;position:absolute;bottom:7px;width:90%;left:5%;border-radius:50%;filter:blur(5px)}.stage small{font-size:12px;opacity:.7}.panel{padding:8px 0}fieldset{border:0;padding:0;margin:0 0 32px;min-width:0}legend{font-size:18px;margin-bottom:16px}.segments{display:flex;background:var(--surface);padding:4px;border-radius:16px;gap:4px}.segments label{flex:1;min-width:0;position:relative;text-align:center;cursor:pointer}.segments input{position:absolute;opacity:0;width:1px;height:1px}.segments span{display:block;padding:12px 8px;border:1px solid transparent;border-radius:12px}.segments input:checked+span{background:var(--canvas);border-color:var(--ink);box-shadow:0 1px 4px #0002}.swatch{display:inline-block;width:12px;height:12px;border-radius:50%;margin-right:6px;border:1px solid #777}.summary{border-top:1px solid var(--line);padding-top:24px;margin:0 0 24px}.summary small{display:block;opacity:.65;margin-bottom:4px}.summary strong{font-weight:400;font-size:20px}.primary{border:0;border-radius:12px;min-height:52px;background:var(--ink);color:var(--canvas);padding:12px 24px;width:100%}.saved{border-left:3px solid var(--ink);padding-left:16px;margin-top:24px}.saved:empty{display:none}footer{font-size:12px;opacity:.7;padding-top:32px}@media(max-width:759px){header{padding:16px}header b{font-size:13px;letter-spacing:1px}.layout{grid-template-columns:1fr;gap:24px}.stage{min-height:270px;padding:16px}.scene{height:210px}.wheel{width:53px;height:53px;border-width:8px;bottom:21px}.car{bottom:38px}.roof{bottom:91px;height:60px}.segments span{padding:12px 5px;font-size:14px}fieldset{margin-bottom:24px}}
</style><header><b>DESIGN STUDY / 01</b><button id="theme" type="button">Dark interface</button></header><main><h1>A different point of view.</h1><p class="intro">Explore two small choices in an original vehicle study. See how a restrained interface keeps the object at the center.</p><div class="layout"><div class="stage"><div class="scene" id="scene" role="img" aria-label="Original vehicle illustration in Chalk with Classic wheels"><div class="shadow"></div><div class="roof"><div class="window"></div></div><div class="car"><div class="headlight"></div></div><div class="wheel a"></div><div class="wheel b"></div></div><small>Original illustration · Not a Porsche model render</small></div><section class="panel" aria-label="Study options"><fieldset><legend>Finish</legend><div class="segments"><label><input type="radio" name="paint" value="chalk" checked><span><i class="swatch" style="background:#b9b6ae"></i>Chalk</span></label><label><input type="radio" name="paint" value="blue"><span><i class="swatch" style="background:#456171"></i>Coastal blue</span></label><label><input type="radio" name="paint" value="red"><span><i class="swatch" style="background:#9f2937"></i>Garnet</span></label></div></fieldset><fieldset><legend>Wheel study</legend><div class="segments"><label><input type="radio" name="wheel" value="Classic" checked><span>Classic</span></label><label><input type="radio" name="wheel" value="Aero"><span>Aero</span></label></div></fieldset><p class="summary" aria-live="polite"><small>YOUR COMBINATION</small><strong id="summary">Chalk · Classic</strong></p><button class="primary" id="save" type="button">Keep this combination</button><p class="saved" id="saved" role="status"></p></section></div><footer>Independent PDS v4 interpretation. Original finish names and illustration; no pricing, vehicle specification, live configuration or order. Choices last only for this page session.</footer></main><script>const colors={chalk:'#b9b6ae',blue:'#456171',red:'#9f2937'},names={chalk:'Chalk',blue:'Coastal blue',red:'Garnet'};function values(){return[document.querySelector('[name=paint]:checked').value,document.querySelector('[name=wheel]:checked').value]}function update(){const[p,w]=values();document.documentElement.style.setProperty('--paint',colors[p]);document.querySelector('#scene').classList.toggle('aero',w==='Aero');document.querySelector('#scene').setAttribute('aria-label',`Original vehicle illustration in ${names[p]} with ${w} wheels`);document.querySelector('#summary').textContent=`${names[p]} · ${w}`;document.querySelector('#saved').textContent=''}document.querySelectorAll('input').forEach(x=>x.addEventListener('change',update));document.querySelector('#save').onclick=()=>{const[p,w]=values();document.querySelector('#saved').textContent=`Kept for this page session: ${names[p]}, ${w}. No order submitted.`};document.querySelector('#theme').onclick=e=>{const dark=document.body.classList.toggle('dark');e.currentTarget.textContent=dark?'Light interface':'Dark interface'};</script></html>
Выбор отделки и колёс обновляет оригинальную иллюстрацию конфигуратора. Это не характеристики продукции Porsche; события нативного сегментированного переключателя показаны в отдельном примере для версии 4.
Два управляемых параметра выбора и сводка, доступная только в текущем сеансе
Нативные элементы p-segmented-control создают события change со значением detail.value; p-button использует событие click и явное указание типа.
TypeScript
import './style.css';
const paints={chalk:'#b9b6ae',blue:'#456171',red:'#9f2937'};
const names={chalk:'Chalk',blue:'Coastal blue',red:'Garnet'};
type Paint=keyof typeof paints;
let paint:Paint='chalk',wheel='Classic';
document.querySelector<HTMLDivElement>('#app')!.innerHTML=`
<main><h1>Explore an original color study</h1>
<p>This specimen is not a real vehicle configurator or order.</p>
<div class="options">
<p-segmented-control id="paint" label="Finish" value="chalk">
<p-segmented-control-item value="chalk">Chalk</p-segmented-control-item>
<p-segmented-control-item value="blue">Coastal blue</p-segmented-control-item>
<p-segmented-control-item value="red">Garnet</p-segmented-control-item>
</p-segmented-control>
<p-segmented-control id="wheel" label="Wheel study" value="Classic">
<p-segmented-control-item value="Classic">Classic</p-segmented-control-item>
<p-segmented-control-item value="Aero">Aero</p-segmented-control-item>
</p-segmented-control>
</div><div class="preview"><div id="swatch" style="height:120px;border-radius:12px"></div>
<p id="summary" aria-live="polite"></p></div>
<div class="actions"><p-button id="save" type="button">Keep this combination</p-button>
<p-button id="scheme" type="button" variant="secondary">Switch color scheme</p-button></div>
<p id="saved" role="status"></p></main>`;
function render(){document.querySelector<HTMLElement>('#swatch')!.style.background=paints[paint];document.querySelector('#summary')!.textContent=`${names[paint]} · ${wheel} wheel study`;document.querySelector('#saved')!.textContent='';}
document.querySelector('#paint')!.addEventListener('change',e=>{const v=(e as CustomEvent<{value:string}>).detail.value;if(v in paints){paint=v as Paint;render();}});
document.querySelector('#wheel')!.addEventListener('change',e=>{wheel=String((e as CustomEvent<{value:string}>).detail.value);render();});
document.querySelector('#save')!.addEventListener('click',()=>{document.querySelector('#saved')!.textContent=`Kept for this page session: ${names[paint]}, ${wheel}. No order submitted.`;});
document.querySelector('#scheme')!.addEventListener('click',()=>{const root=document.documentElement;root.style.colorScheme=root.style.colorScheme==='dark'?'light':'dark';});
render();
Пример не собирает контактные данные, не резервирует автомобиль и не отправляет заказ.
04
Дизайн-система Porsche Настройка AI-агента
Отправная точка для реализации
Настройка нативных веб-компонентов версии 4 с документированной глобальной таблицей стилей и фрагментом загрузчика. В офлайн-примере нет удалённых шрифтов и среды выполнения пакета; нативная компиляция пакета здесь не проверялась.
текст
# In a new Vite vanilla-ts project:
npm create vite@latest pds-specimen -- --template vanilla-ts
cd pds-specimen
npm install
npm install @porsche-design-system/components-js@4
npm install --save-dev lightningcss
// vite.config.ts
import {defineConfig} from 'vite';
import {Features} from 'lightningcss';
import {getLoaderScript} from '@porsche-design-system/components-js/partials';
export default defineConfig({
plugins:[{name:'pds-loader',transformIndexHtml(html){
return html.replace('</body>',getLoaderScript()+'</body>');
}}],
css:{transformer:'lightningcss',lightningcss:{exclude:Features.LightDark}}
});
/* src/style.css */
@import '@porsche-design-system/components-js';
html { color-scheme: light; }
:is(p-button,p-segmented-control,p-segmented-control-item):not(:defined){visibility:hidden}
main{max-width:60rem;margin:auto;padding:clamp(16px,1.25vw + 12px,36px)}
.options{display:grid;gap:32px}
.preview{padding:32px;border-radius:24px;margin-block:32px;border:1px solid currentColor}
.actions{display:flex;gap:16px;flex-wrap:wrap}
# Replace src/main.ts with the example below, then:
npm run dev
Запрос для вашего проекта
Промпт для AI-агента
Создайте композицию PDS версии 4 с обязательными глобальными стилями, фрагментом загрузчика, color-scheme, настоящими адаптивными интервалами и радиусами 12px для элементов управления и 24px для контейнеров. Используйте detail.value события change сегментированного переключателя для двух оригинальных параметров примера, а для локальных действий явно указывайте type=button. Не смешивайте API устаревших обёрток и не представляйте пример как реальную конфигурацию автомобиля.
05
Дизайн-система Porsche Источники и область применения
Независимый справочный материал OpenDesign, ограниченный PDS версии 4. Оригинальные иллюстрации и названия отделки не являются характеристиками автомобилей Porsche, кодами краски или доступными опциями. Транзакции не выполняются.