Porsche Design SystemSearchNavigate to GitHub repository of Porsche Design SystemOpen sidebar
Grid Table of Contents Example The Porsche grid system is based on native CSS Grid for best performance, changing its available columns on mobile (6 content columns + 2 safe zone columns) and desktop view >= 760px viewport width (8-narrow/12-basic/14-extended/16-wide content columns + 2 safe zone columns). It has a size range between 320px and 2560px, using fluid sized columns and gaps. The Porsche grid has to be used on a top level and can't be nested.
Full for Background and Media

Hero Heading

Subline for the Hero Header in Wide Grid

Wide Sidebar
Wide Content
Extended Half for Large Teaser Backgrounds, Media, Image Grids
Extended Half for Large Teaser Backgrounds, Media, Image Grids
Custom (column desktop: 2-9) for Image Grids
Custom (column desktop: 10-15) for Image Grids
Custom (column desktop: 10-14) for Image Grids
Full for Teaser Backgrounds and Media (Former Basic)
Basic for Content in Teaser

Heading in Teaser

Subline or Copy Text in Large Teaser

Some label
Basic for Content Tiles

Heading in Tile

Some label
Basic Half for Content Tiles

Heading in Tile

Some label
Basic Half for Content Tiles

Heading in Tile

Some label
Basic Third for Content Tiles

Heading in Tile

Some label
Basic Third for Content Tiles

Heading in Tile

Some label
Basic Third for Content Tiles

Heading in Tile

Some label
Basic Two Thirds for Content Tiles
Basic One Third for Content Tiles
Custom (desktop: column 3-7) for Content
Custom (desktop: column 9-14) for Content
Narrow for small Components and Content

Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Donec quam felis, ultricies nec, pellentesque eu. Aenean massa.

Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Donec quam felis, ultricies nec, pellentesque eu. Aenean massa.

Narrow Half for small Content Tiles

Experience

Goosebumps, adrenaline: experience the fascination of sports cars - with all different facets and according to your wishes.

Narrow Half for small Content Tiles

Experience

Goosebumps, adrenaline: experience the fascination of sports cars - with all different facets and according to your wishes.

import { ChangeDetectionStrategy, Component, Input } from '@angular/core';
import type { AccordionUpdateEventDetail } from '@porsche-design-system/components-angular';

@Component({
  selector: 'porsche-design-system-app',
  styles: [
    `
      @use '@porsche-design-system/components-angular/styles' as *;

      // Visualize Grid
      .visualize-grid {
        @include pds-grid;
        position: fixed;
        inset: 0;
        pointer-events: none;

        > span {
          background: rgba(0, 0, 255, 0.1);
          &:first-child,
          &:last-child {
            background: rgba(125, 0, 255, 0.1);
          }

          @include pds-media-query-max('s') {
            &:nth-child(8) {
              background: rgba(125, 0, 255, 0.1);
            }
            &:nth-child(n + 9) {
              display: none;
            }
          }
        }
      }

      // Tile
      @mixin tile($color, $padding: 'medium', $border-radius: true) {
        $color-map: (
          'blue': rgba(0, 0, 255, 0.25),
          'green': rgba(0, 255, 0, 0.25),
          'purple': rgba(255, 0, 255, 0.25),
          'yellow': rgba(255, 255, 0, 0.25),
          'orange': rgba(255, 125, 0, 0.25),
        );
        @if $padding == 'medium' {
          padding: $pds-spacing-fluid-medium;
        } @else if $padding == 'small' {
          padding: $pds-spacing-fluid-small;
        } @else {
          padding: 0;
        }
        @if $border-radius == true {
          border-radius: $pds-border-radius-large;
        }
        background: map-get($color-map, $color);
      }

      // Typography
      .info {
        @include pds-text-x-small;
        display: inline-block;
        vertical-align: top;
        color: $pds-theme-light-primary;
        border-radius: $pds-border-radius-small;
        margin-bottom: $pds-spacing-fluid-small;
        padding: $pds-spacing-static-x-small $pds-spacing-static-small;
        background: $pds-theme-light-state-hover;

        .hero-media &,
        .teaser-media &,
        .narrow-content & {
          margin-left: $pds-spacing-static-small;
          margin-top: $pds-spacing-static-small;
        }
      }

      .display {
        @include pds-display-large;
        color: $pds-theme-light-primary;
        margin: 0;
      }

      .heading {
        @include pds-heading-large;
        color: $pds-theme-light-primary;
        margin: 0;
      }

      .heading-x-large {
        @include pds-heading-x-large;
        color: $pds-theme-light-primary;
        margin: 0;
      }

      .text {
        @include pds-text-small;
        color: $pds-theme-light-primary;
        margin: $pds-spacing-fluid-x-small 0 0;
      }

      .text-large {
        @include pds-text-large;
        color: $pds-theme-light-primary;
        margin: $pds-spacing-fluid-x-small 0 0;
      }

      p-button {
        margin-top: $pds-spacing-fluid-medium;
      }

      // Hero
      .hero-grid {
        @include pds-grid;
        align-items: end;
      }

      .hero-media {
        @include tile('blue', false, false);
        grid-column: $pds-grid-full-column-start / $pds-grid-full-column-end;
        grid-row: 1;
        height: clamp(300px, 50vh, 500px);
      }

      .hero-header {
        @include tile('green', false, false);
        grid-column: $pds-grid-wide-column-start / $pds-grid-wide-column-end;
        grid-row: 1;
        padding-bottom: $pds-spacing-fluid-medium;
        display: flex;
        flex-direction: column;
        justify-content: flex-end;
      }

      // Wide Content
      .wide-grid {
        @include pds-grid;
        margin-top: $pds-spacing-fluid-large;
      }

      .wide-sidebar {
        @include tile('orange');
        grid-column: $pds-grid-wide-column-start / $pds-grid-wide-column-end;

        @include pds-media-query-min('s') {
          grid-column: $pds-grid-wide-column-start / span 5;
        }
      }

      .wide-content {
        @include tile('orange');
        grid-column: $pds-grid-wide-column-start / $pds-grid-wide-column-end;

        @include pds-media-query-min('s') {
          grid-column: span 11 / $pds-grid-wide-column-end;
        }
      }

      // Extended Content
      .extended-content-grid {
        @include pds-grid;
        margin-top: $pds-spacing-fluid-large;
      }

      .extended-content-half-left {
        @include tile('green');
        grid-column: $pds-grid-extended-column-start / $pds-grid-extended-span-one-half;
      }

      .extended-content-half-right {
        @include tile('green');
        grid-column: $pds-grid-extended-span-one-half / $pds-grid-extended-column-end;
      }

      // Masonry
      .masonry-grid {
        @include pds-grid;
        margin-top: $pds-grid-gap;
      }

      .masonry-custom-1 {
        @include tile('green');
        grid-column: $pds-grid-extended-column-start / $pds-grid-extended-column-end;
        @include pds-media-query-min('s') {
          grid-column: $pds-grid-extended-column-start / span 8;
          grid-row: span 2;
        }
      }

      .masonry-custom-2 {
        @include tile('green');
        grid-column: $pds-grid-extended-column-start / $pds-grid-extended-span-one-half;
        @include pds-media-query-min('s') {
          grid-column: span 6 / $pds-grid-extended-span-one-half;
        }
      }

      .masonry-custom-3 {
        @include tile('green');
        grid-column: $pds-grid-extended-span-one-half / $pds-grid-extended-column-end;
        @include pds-media-query-min('s') {
          grid-column: span 5 / $pds-grid-extended-span-one-half;
        }
      }

      // Teaser
      .teaser-grid {
        @include pds-grid;
        margin-top: $pds-spacing-fluid-large;
      }

      .teaser-media {
        @include tile('blue', false, false);
        grid-column: $pds-grid-full-column-start / $pds-grid-full-column-end;
        grid-row: 1;
      }

      .teaser-content {
        @include tile('purple', false, false);
        grid-column: $pds-grid-basic-column-start / $pds-grid-basic-column-end;
        grid-row: 1;
        margin: $pds-spacing-fluid-large 0;
      }

      // Basic Content
      .basic-content-grid {
        @include pds-grid;
        margin-top: $pds-spacing-fluid-large;
      }

      .basic-content {
        @include tile('purple');
        grid-column: $pds-grid-basic-column-start / $pds-grid-basic-column-end;
      }

      .basic-content-half-left {
        @include tile('purple');
        grid-column: $pds-grid-basic-column-start / $pds-grid-basic-span-one-half;
      }

      .basic-content-half-right {
        @include tile('purple');
        grid-column: $pds-grid-basic-span-one-half / $pds-grid-basic-column-end;
      }

      .basic-content-one-third-left {
        @include tile('purple');
        grid-column: $pds-grid-basic-column-start / $pds-grid-basic-column-end;
        @include pds-media-query-min('s') {
          grid-column: $pds-grid-basic-column-start / $pds-grid-basic-span-one-third;
        }
      }

      .basic-content-one-third-follow {
        @include tile('purple');
        grid-column: $pds-grid-basic-column-start / $pds-grid-basic-column-end;
        @include pds-media-query-min('s') {
          grid-column: $pds-grid-basic-span-one-third;
        }
      }

      .basic-content-one-third-right {
        @include tile('purple');
        grid-column: $pds-grid-basic-column-start / $pds-grid-basic-column-end;
        @include pds-media-query-min('s') {
          grid-column: $pds-grid-basic-span-one-third / $pds-grid-basic-column-end;
        }
      }

      .basic-content-two-thirds-left {
        @include tile('purple');
        grid-column: $pds-grid-basic-column-start / $pds-grid-basic-column-end;
        @include pds-media-query-min('s') {
          grid-column: $pds-grid-basic-column-start / $pds-grid-basic-span-two-thirds;
        }
      }

      .basic-content-custom-left {
        @include tile('purple');
        grid-column: $pds-grid-basic-column-start / $pds-grid-basic-column-end;
        @include pds-media-query-min('s') {
          grid-column: $pds-grid-basic-column-start / span 5;
        }
      }

      .basic-content-custom-right {
        @include tile('purple');
        grid-column: span 6 / $pds-grid-basic-column-end;
      }

      // Narrow Content
      .narrow-content-grid {
        @include pds-grid;
        margin-top: $pds-spacing-fluid-large;
      }

      .narrow-content {
        @include tile('yellow', false);
        grid-column: $pds-grid-narrow-column-start / $pds-grid-narrow-column-end;
      }

      .narrow-content-half-left {
        @include tile('yellow', 'small');
        grid-column: $pds-grid-narrow-column-start / $pds-grid-narrow-span-one-half;
      }

      .narrow-content-half-right {
        @include tile('yellow', 'small');
        grid-column: $pds-grid-narrow-span-one-half / $pds-grid-narrow-column-end;
      }
    `,
  ],
  template: `
    <div [ngStyle]="{ transform: 'translate3d(0px, 0px, 0px)' }">
      <div class="visualize-grid" *ngIf="visualizeGrid">
        <span *ngFor="let n of counter(18)" class="visualize-grid-columns"></span>
      </div>
      <div class="hero-grid">
        <div class="hero-media">
          <span class="info"><b>Full</b> for Background and Media</span>
        </div>
        <div class="hero-header">
          <h1 class="display">Hero Heading</h1>
          <p class="text-large">Subline for the Hero Header in Wide Grid</p>
        </div>
      </div>
      <div class="wide-grid">
        <div class="wide-sidebar">
          <span class="info"><b>Wide Sidebar</b></span>
          <p-accordion heading="Some Heading" tag="h3"></p-accordion>
          <p-accordion heading="Some Heading" tag="h3"></p-accordion>
          <p-accordion heading="Some Heading" tag="h3"></p-accordion>
        </div>
        <div class="wide-content">
          <span class="info"><b>Wide Content</b></span>
        </div>
      </div>
      <div class="extended-content-grid">
        <div class="extended-content-half-left">
          <span class="info"><b>Extended Half</b> for Large Teaser Backgrounds, Media, Image Grids</span>
        </div>
        <div class="extended-content-half-right">
          <span class="info"><b>Extended Half</b> for Large Teaser Backgrounds, Media, Image Grids</span>
        </div>
      </div>
      <div class="masonry-grid">
        <div class="masonry-custom-1">
          <span class="info"><b>Custom (column desktop: 2-9)</b> for Image Grids</span>
        </div>
        <div class="masonry-custom-2">
          <span class="info"><b>Custom (column desktop: 10-15)</b> for Image Grids</span>
        </div>
        <div class="masonry-custom-3">
          <span class="info"><b>Custom (column desktop: 10-14)</b> for Image Grids</span>
        </div>
      </div>
      <div class="teaser-grid">
        <div class="teaser-media">
          <span class="info"><b>Full</b> for Teaser Backgrounds and Media (Former Basic)</span>
        </div>
        <div class="teaser-content">
          <span class="info"><b>Basic</b> for Content in Teaser</span>
          <h2 class="heading-x-large">Heading in Teaser</h2>
          <p class="text">Subline or Copy Text in Large Teaser</p>
          <p-button variant="secondary">Some label</p-button>
        </div>
      </div>
      <div class="basic-content-grid">
        <div class="basic-content">
          <span class="info"><b>Basic</b> for Content Tiles</span>
          <h3 class="heading">Heading in Tile</h3>
          <p-button variant="secondary">Some label</p-button>
        </div>
        <div class="basic-content-half-left">
          <span class="info"><b>Basic Half</b> for Content Tiles</span>
          <h3 class="heading">Heading in Tile</h3>
          <p-button variant="secondary">Some label</p-button>
        </div>
        <div class="basic-content-half-right">
          <span class="info"><b>Basic Half</b> for Content Tiles</span>
          <h3 class="heading">Heading in Tile</h3>
          <p-button variant="secondary">Some label</p-button>
        </div>
        <div class="basic-content-one-third-left">
          <span class="info"><b>Basic Third</b> for Content Tiles</span>
          <h3 class="heading">Heading in Tile</h3>
          <p-button variant="secondary">Some label</p-button>
        </div>
        <div class="basic-content-one-third-follow">
          <span class="info"><b>Basic Third</b> for Content Tiles</span>
          <h3 class="heading">Heading in Tile</h3>
          <p-button variant="secondary">Some label</p-button>
        </div>
        <div class="basic-content-one-third-follow">
          <span class="info"><b>Basic Third</b> for Content Tiles</span>
          <h3 class="heading">Heading in Tile</h3>
          <p-button variant="secondary">Some label</p-button>
        </div>
        <div class="basic-content-two-thirds-left">
          <span class="info kbBcQV"><b>Basic Two Thirds</b> for Content Tiles</span>
        </div>
        <div class="basic-content-one-third-right">
          <span class="info"><b>Basic One Third</b> for Content Tiles</span>
        </div>
        <div class="basic-content-custom-left">
          <span class="info"><b>Custom (desktop: column 3-7)</b> for Content</span>
        </div>
        <div class="basic-content-custom-right">
          <span class="info"><b>Custom (desktop: column 9-14)</b> for Content</span>
        </div>
      </div>
      <div class="narrow-content-grid">
        <div class="narrow-content">
          <span class="info"><b>Narrow</b> for small Components and Content</span>
          <p-accordion heading="Some Heading" tag="h3" [open]="isAccordion1Open" (update)="onAccordion1Update($event)"
            ><p class="text">
              Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Donec quam
              felis, ultricies nec, pellentesque eu. Aenean massa.
            </p></p-accordion
          >
          <p-accordion heading="Some Heading" tag="h3" [open]="isAccordion2Open" (update)="onAccordion2Update($event)"
            ><p class="text">
              Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Donec quam
              felis, ultricies nec, pellentesque eu. Aenean massa.
            </p></p-accordion
          >
        </div>
        <div class="narrow-content-half-left">
          <span class="info"><b>Narrow</b> Half for small Content Tiles</span>
          <h3 class="heading">Experience</h3>
          <p class="text">
            Goosebumps, adrenaline: experience the fascination of sports cars - with all different facets and according to
            your wishes.
          </p>
        </div>
        <div class="narrow-content-half-right">
          <span class="info"><b>Narrow</b> Half for small Content Tiles</span>
          <h3 class="heading">Experience</h3>
          <p class="text">
            Goosebumps, adrenaline: experience the fascination of sports cars - with all different facets and according to
            your wishes.
          </p>
        </div>
      </div>
    </div>
  `,
  changeDetection: ChangeDetectionStrategy.OnPush,
  standalone: false,
})
export class ExampleComponent {
  counter(i: number) {
    return new Array(i);
  }
  @Input() visualizeGrid = true;
  isAccordion1Open = false;
  isAccordion2Open = false;

  onAccordion1Update(e: CustomEvent<AccordionUpdateEventDetail>) {
    this.isAccordion1Open = e.detail.open;
  }
  onAccordion2Update(e: CustomEvent<AccordionUpdateEventDetail>) {
    this.isAccordion2Open = e.detail.open;
  }
}
Usage Grid Areas: Basic-Grid 12 Columns: This is the default and should contain all productive content, such as copy, graphics, and descriptive imagery (or at least the main focus of the image). Extended-Grid 14 Columns: Containers and images can be stretched to the extended grid to cluster content better or create a more immersive moment. Wide-Grid 16 Columns: Productive applications with, for example, a sidebar, can make use of the wide grid. Further interactive/productive modules can make use of the full 16 columns. Full-bleed: For immersive moments, images and background colors can be stretched to the full width of the viewport. This does not correspond to the grid. Note: that the Basic-, Extended-, and Wide-Grid all equal 6 columns on mobile viewports. Do: Use the grid for a consistent appearance over all touchpoints. Align all left-aligned-headlines on one vertical line (left border of basic-grid). Set at least the image focus for larger imagery within the basic grid. Don't: Don't scale elements within the grid bigger than the maximum specification for 1920px. Styles The styles are available as JavaScript and SCSS version. Look at the example above to see how the styles work. JS When using JSS, styled-components etc. JavaScript styles can be imported by: import { … } from '@porsche-design-system/components-{js|angular|react|vue}/styles';. When using vanilla-extract JavaScript styles can be imported by: import { … } from '@porsche-design-system/components-{js|angular|react|vue}/styles/vanilla-extract';. gridStyle gridGap gridNarrow gridNarrowColumnStart gridNarrowColumnEnd gridNarrowSpanOneHalf gridNarrowOffset gridNarrowOffsetBase gridNarrowOffsetS gridNarrowOffsetXXL gridBasic gridBasicColumnStart gridBasicColumnEnd gridBasicSpanOneHalf gridBasicSpanOneThird gridBasicSpanTwoThirds gridBasicOffset gridBasicOffsetBase gridBasicOffsetS gridBasicOffsetXXL gridExtended gridExtendedColumnStart gridExtendedColumnEnd gridExtendedSpanOneHalf gridExtendedOffset gridExtendedOffsetBase gridExtendedOffsetS gridExtendedOffsetXXL gridWide gridWideColumnStart gridWideColumnEnd gridWideOffset gridWideOffsetBase gridWideOffsetS gridWideOffsetXXL gridFull gridFullColumnEnd gridFullColumnStart gridFullOffset SCSS SCSS styles can be imported by @use '@porsche-design-system/components-{js|angular|react|vue}/styles' as *; @mixin pds-grid() $pds-grid-gap $pds-grid-narrow-column-start $pds-grid-narrow-column-end $pds-grid-narrow-span-one-half $pds-grid-narrow-offset-base $pds-grid-narrow-offset-s $pds-grid-narrow-offset-xxl $pds-grid-basic-column-start $pds-grid-basic-column-end $pds-grid-basic-span-one-half $pds-grid-basic-span-one-third $pds-grid-basic-span-two-thirds $pds-grid-basic-offset-base $pds-grid-basic-offset-s $pds-grid-basic-offset-xxl $pds-grid-extended-column-start $pds-grid-extended-column-end $pds-grid-extended-span-one-half $pds-grid-extended-offset-base $pds-grid-extended-offset-s $pds-grid-extended-offset-xxl $pds-grid-wide-column-start $pds-grid-wide-column-end $pds-grid-wide-offset-base $pds-grid-wide-offset-s $pds-grid-wide-offset-xxl $pds-grid-full-column-start $pds-grid-full-column-end $pds-grid-full-offset
Global settingsThemeChanges the theme of the application and any Porsche Design System component. It's possible to choose between forced theme light and dark. It's also possible to use auto, which applies light or dark theme depending on the operating system settings automatically.LightDarkAuto (sync with operating system)DirectionChanges the direction of HTML elements, mostly used on<html> tag to support languages which are read from right to left like e.g. Arabic.LTR (left-to-right)RTL (right-to-left)AutoText ZoomChanges the text size and values with unit rem or em relatively. This setting can be defined in browser settings for any website or by an application itself on<html> tag. To achieve WCAG 2.2 AA compliance it's obligatory to support text zoom up to at least 200%.100%130%150%200%