Skip to contentPorsche Design System
You are currently viewing an earlier release of the Porsche Design System.Switch to the latest Porsche Design System documentation.
SearchGitHub repository of Porsche Design SystemOpen settings sidebar
Button Table of Contents Form When used as a submit button, the name and value props are submitted as a pair as part of the form data.
Button AButton B
Last submitted data: none
Open in Stackblitz
<!doctype html>
<html lang="en" class="scheme-light-dark">
<head>
  <title></title>
</head>
<body class="bg-canvas">

<form class="flex gap-fluid-sm">
  <p-button name="option" value="A" type="submit">Button A</p-button>
  <p-button name="option" value="B" type="submit">Button B</p-button>
</form>

<p-text>Last submitted data: none</p-text>
<script>
  const debugElement = document.querySelector('p-text');
  const form = document.querySelector('form');
  form.addEventListener('submit', (e) => {
    e.preventDefault();
    const formData = Array.from(new FormData(e.target, e.submitter).entries())[0];
    debugElement.innerText = `Last submitted data: ${formData.join('=') || 'none'}`;
  });
</script>
</body>
</html>
Form Attribute When a button is used as a submit or reset button outside a form, the form attribute can be utilized to explicitly associate the button with a specific form element. When using the p-button component as a submit or reset button outside a form, it relies on the ElementInternals API, which has limited browser support.

As of now, the submitter in the form event is null because the button cannot be accessed within the shadow DOM to be passed as an argument to the requestSubmit() function ( WICG/webcomponents#814).


Additionally, custom components using ElementInternals may include all values of elements with the same name attribute in form data, rather than only the value of the triggering element, deviating from native form behavior.
SubmitReset
Last submitted data: none
Open in Stackblitz
<!doctype html>
<html lang="en" class="scheme-light-dark">
<head>
  <title></title>
</head>
<body class="bg-canvas">

<form id="some-form">
  <p-textarea name="some-name" label="Some Label"></p-textarea>
</form>

<div class="flex gap-fluid-sm mt-fluid-sm">
  <p-button type="submit" form="some-form">Submit</p-button>
  <p-button type="reset" form="some-form">Reset</p-button>
</div>

<p-text>Last submitted data: none</p-text>
<script>
  const debugElement = document.querySelector('p-text');
  const form = document.querySelector('form');
  form.addEventListener('submit', (e) => {
    e.preventDefault();
    const formData = new FormData(form);
    debugElement.innerText = `Last submitted data: ${formData.get('some-name') || 'none'} `;
  });
</script>
</body>
</html>
Custom AI Styling: Drop Shadow 🧪 Experimental: This example shows what's technically possible with the exposed --p-button-bg and --p-button-fg CSS variables. It is not approved by brand compliance and must not be treated as an official AI button style. An elevated button on a plain background, combining a custom foreground/background pair with a drop shadow from the --p-shadow-lg token. Hover is scoped with :not(:disabled, :state(loading)) so the styling isn't applied while the button is disabled or loading. When you override the colors, you are responsible for sufficient contrast (at least 4.5:1 between label and background) in both light and dark color scheme.
Ask AI assistantAsk AI assistant
Open in Stackblitz
<!doctype html>
<html lang="en" class="scheme-light-dark">
<head>
  <title></title>
</head>
<body class="bg-canvas">

<style>
  .custom-ai-shadow {
  --p-button-bg: #fff;
  --p-button-fg: #000;
  box-shadow: var(--p-shadow-lg);
}

.custom-ai-shadow:not(:disabled, :state(loading)):hover {
  --p-button-bg: var(--p-color-frosted-strong);
  --p-button-fg: var(--p-color-primary);
}
</style>

<div class="flex flex-wrap gap-static-lg items-start">
  <p-button class="custom-ai-shadow" icon="ai-chat" hide-label="true">
    Ask AI assistant
  </p-button>
  <p-button class="custom-ai-shadow" icon="ai-chat">
    Ask AI assistant
  </p-button>
</div>
<script>

</script>
</body>
</html>
Custom AI Styling: Gradient Glow 🧪 Experimental: This example demonstrates the technical possibilities of styling around the button host element. It is not approved by brand compliance and must not be treated as an official AI button style. The animated gradient glow is built with two decorative pseudo-elements (::before and ::after) on the p-button host. They sit behind the button via z-index: -1 and reuse its shape with border-radius: inherit, so the button's own shadow DOM, focus ring and keyboard behavior stay untouched. Keep the following accessibility constraints in mind when adopting such a pattern: The animation is disabled via @media (prefers-reduced-motion: reduce) for users who requested reduced motion. The decorative pseudo-elements are hidden via @media (forced-colors: active), since the gradient carries no meaning and would otherwise be flattened to a system color in High Contrast Mode. The label and icon colors are overridden with tokens that keep sufficient contrast in both color schemes — never rely on the glow to convey state or meaning.
Ask AI assistantAsk AI assistant
Open in Stackblitz
<!doctype html>
<html lang="en" class="scheme-light-dark">
<head>
  <title></title>
</head>
<body class="bg-canvas">

<style>
  .custom-ai-orb {
  --p-button-bg: var(--p-color-canvas);
  --p-button-fg: var(--p-color-primary);
  position: relative;
  z-index: 0;
}

.custom-ai-orb:not(:disabled, :state(loading)):hover {
  --p-button-bg: var(--p-color-frosted-strong);
  --p-button-fg: #fff;
}

.custom-ai-orb::before,
.custom-ai-orb::after {
  content: '';
  position: absolute;
  inset: 0;
  z-index: -1;
  border-radius: inherit;
  background: linear-gradient(45deg, #00a8ff, #0151e1, #2ae3ff, #bff0ff, #0151e1, #00a8ff);
  background-size: 400%;
  animation: custom-ai-orb-gradient 20s linear infinite;
}

.custom-ai-orb::after {
  filter: blur(10px);
  animation:
    custom-ai-orb-gradient 20s linear infinite,
    custom-ai-orb-float 8s ease-in-out infinite;
}

@keyframes custom-ai-orb-gradient {
  0% {
    background-position: 0 0;
  }
  50% {
    background-position: 300% 0;
  }
  100% {
    background-position: 0 0;
  }
}

@keyframes custom-ai-orb-float {
  0% {
    transform: scale(1) rotate(0deg);
  }
  50% {
    transform: scale(1.02) rotate(0.5deg);
  }
  100% {
    transform: scale(1) rotate(0deg);
  }
}

/* Respect the user's motion preference */
@media (prefers-reduced-motion: reduce) {
  .custom-ai-orb::before,
  .custom-ai-orb::after {
    animation: none;
  }
}

/* Decorative gradient is not conveyed in forced-colors mode */
@media (forced-colors: active) {
  .custom-ai-orb::before,
  .custom-ai-orb::after {
    display: none;
  }
}
</style>

<div class="flex flex-wrap gap-static-lg items-start">
  <p-button class="custom-ai-orb" icon="ai-chat" hide-label="true">
    Ask AI assistant
  </p-button>
  <p-button class="custom-ai-orb" icon="ai-chat">
    Ask AI assistant
  </p-button>
</div>
<script>

</script>
</body>
</html>
v4.8.0v2v1
Global settingsColor SchemeAll color tokens use the light-dark() CSS function. Set the theme via the CSS color-scheme property: light for light mode, dark for dark mode, or light dark to follow the user's system preference.LightDarkLight DarkDirectionThe dir global attribute in HTML changes the direction of text and other content within an element. It's most often used on the <html> tag to set the entire page's direction, which is crucial for supporting languages that are written from right to left (RTL), such as Arabic and Hebrew. For example, using <html dir="rtl"> makes the entire page display from right to left, adjusting the layout and text flow accordingly.LTR (left-to-right)RTL (right-to-left)Text ZoomTo ensure accessibility and comply with WCAG 2.2 AA standards, it is mandatory for web content to support text resizing up to at least 200% without loss of content or functionality. Using relative units like rem is a best practice for achieving this, as they allow the text to scale uniformly based on the user's browser settings.100%130%150%200%