Banners
Banners are components that deliver main image and content in various configurations.
Responsive Display
Display blocks that switch between horizontal/vertical arrangement based on parent container's size.
<template>
<div class="grid md:flex md:flex-row flex-wrap gap-6 max-w-[1540px]">
<div
v-for="{ image, title, subtitle, description, buttonText, backgroundColor, reverse } in displayDetails"
:key="title"
:class="[
'relative flex md:max-w-[1536px] md:[&:not(:first-of-type)]:flex-1 md:first-of-type:w-full @container group',
backgroundColor,
]"
>
<a
class="absolute w-full h-full z-1 focus-visible:outline focus-visible:rounded-lg"
:aria-label="title"
href="#"
/>
<div
:class="[
'flex justify-between overflow-hidden grow flex-col @md:flex-row',
{ '@md:flex-row-reverse flex-col-reverse': reverse },
]"
>
<div
class="grow flex flex-col justify-center items-start p-4 @sm:p-6 @3xl:p-10 max-w-1/2 items-center text-center @md:items-start @md:text-start"
>
<p class="uppercase typography-text-xs block font-medium tracking-widest @3xl:typography-headline-6">
{{ subtitle }}
</p>
<h2 class="mb-4 mt-2 font-semibold typography-display-3 -tracking-wide @3xl:typography-display-1">
{{ title }}
</h2>
<p class="typography-text-base block mb-4 @3xl:typography-text-lg">
{{ description }}
</p>
<SfButton
blank
class="text-white bg-neutral-700 hover:bg-neutral-800 active:bg-neutral-900 group-hover:bg-neutral-800 group-active:bg-neutral-900 group-has-[:focus-visible]:outline group-has-[:focus-visible]:outline-offset pointer-events-none"
tabindex="-1"
>{{ buttonText }}</SfButton
>
</div>
<div class="flex shrink-0 items-center w-full @md:w-1/2 @md:self-start @md:object-contain">
<img :src="image" :alt="title" class="w-full" />
</div>
</div>
</div>
</div>
</template>
<script lang="ts" setup>
import { SfButton } from '@storefront-ui/vue';
const displayDetails = [
{
image: 'https://storage.googleapis.com/sfui_docs_artifacts_bucket_public/production/display-2.png',
title: 'Pack it Up',
subtitle: 'Be active',
description: 'Explore the great outdoors with our backpacks',
buttonText: 'Discover now',
reverse: true,
backgroundColor: 'bg-warning-200',
},
{
image: 'https://storage.googleapis.com/sfui_docs_artifacts_bucket_public/production/display.png',
title: 'Sunny Days Ahead',
subtitle: 'Be inspired',
description: 'Step out in style with our sunglasses collection',
buttonText: 'Discover now',
reverse: true,
backgroundColor: 'bg-negative-200',
},
];
</script>
Horizontal Display
Horizontal display block with image and content to the side.
<template>
<div class="grid md:flex md:flex-row flex-wrap gap-6 max-w-[1540px]">
<div
v-for="{ image, title, subtitle, description, buttonText, backgroundColor, reverse } in displayDetails"
:key="title"
:class="[
'relative flex md:max-w-[1536px] md:[&:not(:first-of-type)]:flex-1 md:first-of-type:w-full @container group',
backgroundColor,
]"
>
<a
class="absolute w-full h-full z-1 focus-visible:outline focus-visible:rounded-lg"
:aria-label="title"
href="#"
/>
<div :class="['flex justify-between overflow-hidden grow', { 'flex-row-reverse': reverse }]">
<div class="grow flex flex-col justify-center items-start p-4 @sm:p-6 @3xl:p-10 max-w-1/2">
<p class="uppercase typography-text-xs block font-medium tracking-widest @3xl:typography-headline-6">
{{ subtitle }}
</p>
<h2 class="mb-4 mt-2 font-semibold typography-display-3 -tracking-wide @3xl:typography-display-1">
{{ title }}
</h2>
<p class="typography-text-base block mb-4 @3xl:typography-text-lg">
{{ description }}
</p>
<SfButton
blank
class="text-white bg-neutral-700 hover:bg-neutral-800 active:bg-neutral-900 group-hover:bg-neutral-800 group-active:bg-neutral-900 group-has-[:focus-visible]:outline group-has-[:focus-visible]:outline-offset pointer-events-none"
tabindex="-1"
>{{ buttonText }}</SfButton
>
</div>
<div class="shrink-0 w-1/2 self-start object-contain">
<img :src="image" :alt="title" class="w-full" />
</div>
</div>
</div>
</div>
</template>
<script lang="ts" setup>
import { SfButton } from '@storefront-ui/vue';
const displayDetails = [
{
image: 'https://storage.googleapis.com/sfui_docs_artifacts_bucket_public/production/display.png',
title: 'Sunny Days Ahead',
subtitle: 'Be inspired',
description: 'Step out in style with our sunglasses collection',
buttonText: 'Discover now',
reverse: false,
backgroundColor: 'bg-negative-200',
},
{
image: 'https://storage.googleapis.com/sfui_docs_artifacts_bucket_public/production/display-2.png',
title: 'Pack it Up',
subtitle: 'Be active',
description: 'Explore the great outdoors with our backpacks',
buttonText: 'Discover now',
reverse: true,
backgroundColor: 'bg-warning-200',
},
{
image: 'https://storage.googleapis.com/sfui_docs_artifacts_bucket_public/production/display-3.png',
title: 'Fresh and Bold',
subtitle: 'New collection',
description: 'Add a pop up color to your outfit',
buttonText: 'Discover now',
reverse: false,
backgroundColor: 'bg-secondary-200',
},
];
</script>
Vertical Display
Vertical display block with image and content below or above it.
<template>
<div class="flex flex-col gap-6 md:flex-row">
<div
v-for="{ title, subtitle, description, callToAction, image, backgroundColor, reverse } in displayDetails"
:key="title"
:class="[
`relative flex flex-col justify-between rounded-md md:items-center md:basis-1/2 ${backgroundColor} @container group`,
{ 'flex-col-reverse': reverse },
]"
>
<a
class="absolute w-full h-full z-1 focus-visible:outline focus-visible:rounded-lg"
:aria-label="title"
href="#"
/>
<div class="flex flex-col items-center p-4 @sm:p-6 text-center @3xl:p-10">
<p class="uppercase typography-text-xs block font-medium tracking-widest @3xl:typography-headline-6">
{{ subtitle }}
</p>
<h2 class="mb-4 mt-2 font-semibold typography-display-3 -tracking-wide @3xl:typography-display-1">
{{ title }}
</h2>
<p class="typography-text-base block mb-4 @3xl:typography-text-lg">
{{ description }}
</p>
<SfButton
blank
class="text-white bg-neutral-700 hover:bg-neutral-800 active:bg-neutral-900 group-hover:bg-neutral-800 group-active:bg-neutral-900 group-has-[:focus-visible]:outline group-has-[:focus-visible]:outline-offset pointer-events-none"
tabindex="-1"
>
{{ callToAction }}
</SfButton>
</div>
<div class="flex items-center w-full">
<img :src="image" :alt="title" class="w-full" />
</div>
</div>
</div>
</template>
<script lang="ts" setup>
import { SfButton } from '@storefront-ui/vue';
const displayDetails = [
{
title: 'Pack it Up',
subtitle: 'Be active',
description: 'Explore the great outdoors with our backpacks',
callToAction: 'Discover now',
image: 'https://storage.googleapis.com/sfui_docs_artifacts_bucket_public/production/display-2.png',
backgroundColor: 'bg-warning-200',
reverse: false,
},
{
title: 'Sunny Days Ahead',
subtitle: 'Be inspired',
description: 'Step out in style with our sunglasses collection',
callToAction: 'Discover now',
image: 'https://storage.googleapis.com/sfui_docs_artifacts_bucket_public/production/display.png',
backgroundColor: 'bg-negative-200',
reverse: true,
},
];
</script>
Multiple vertical Displays
Four vertical displays in row on desktop.
<template>
<div class="flex flex-col gap-6 md:flex-row">
<div class="flex flex-col grow gap-6 md:flex-row">
<div
v-for="{ title, subtitle, description, callToAction, image, backgroundColor, reverse } in displayDetails"
:key="title"
:class="[
`relative flex flex-col justify-between rounded-md md:items-center md:basis-1/2 ${backgroundColor} @container group`,
{ 'flex-col-reverse': reverse },
]"
>
<a
class="absolute w-full h-full z-1 focus-visible:outline focus-visible:rounded-lg"
:aria-label="title"
href="#"
/>
<div class="flex flex-col p-4 @sm:p-6 text-center items-center @3xl:p-10">
<p class="uppercase typography-text-xs block font-medium tracking-widest @3xl:typography-headline-6">
{{ subtitle }}
</p>
<h2 class="mb-4 mt-2 font-semibold typography-display-3 -tracking-wide @3xl:typography-display-1">
{{ title }}
</h2>
<p class="typography-text-base block mb-4 @3xl:typography-text-lg">
{{ description }}
</p>
<SfButton
blank
class="text-white bg-neutral-700 hover:bg-neutral-800 active:bg-neutral-900 group-hover:bg-neutral-800 group-active:bg-neutral-900 group-has-[:focus-visible]:outline group-has-[:focus-visible]:outline-offset pointer-events-none"
tabindex="-1"
>
{{ callToAction }}
</SfButton>
</div>
<div class="flex items-center w-full">
<img :src="image" :alt="title" class="w-full" />
</div>
</div>
</div>
</div>
</template>
<script lang="ts" setup>
import { SfButton } from '@storefront-ui/vue';
const displayDetails = [
{
title: 'Pack it Up',
subtitle: 'Be active',
description: 'Explore the great outdoors with our backpacks',
callToAction: 'Discover now',
image: 'https://storage.googleapis.com/sfui_docs_artifacts_bucket_public/production/display-2.png',
backgroundColor: 'bg-warning-200',
reverse: false,
},
{
title: 'Sunny Days Ahead',
subtitle: 'Be inspired',
description: 'Step out in style with our sunglasses collection',
callToAction: 'Discover now',
image: 'https://storage.googleapis.com/sfui_docs_artifacts_bucket_public/production/display.png',
backgroundColor: 'bg-negative-200',
reverse: true,
},
{
title: 'Fresh and Bold',
subtitle: 'New collection',
description: 'Add a pop up color to your outfit',
callToAction: 'Discover now',
image: 'https://storage.googleapis.com/sfui_docs_artifacts_bucket_public/production/display-3.png',
backgroundColor: 'bg-secondary-200',
reverse: false,
},
];
</script>
Display With Image Overlay
Display block with image filling all of its background area.
<template>
<div class="max-w-[1540px]">
<div
v-for="{ title, subtitle, description, buttonText, backgroundImage } in displayDetails"
:key="title"
class="relative flex text-white max-w-[1536px] @container group"
>
<a
class="absolute w-full h-full z-1 focus-visible:outline focus-visible:rounded-lg"
:aria-label="title"
href="#"
/>
<div class="h-[680px] @3xl:h-auto @3xl:aspect-[2] flex justify-center overflow-hidden grow">
<div class="grow flex flex-col justify-center items-center text-center p-4 @sm:p-6 @3xl:p-10 max-w-1/2">
<p class="uppercase typography-text-xs block font-medium tracking-widest @3xl:typography-headline-6">
{{ subtitle }}
</p>
<h2 class="mb-4 mt-2 font-semibold typography-display-3 -tracking-wide @3xl:typography-display-1">
{{ title }}
</h2>
<p class="typography-text-base block mb-4 @3xl:typography-text-lg">
{{ description }}
</p>
<SfButton
blank
class="w-[200px] bg-white text-primary-700 ring-secondary-400 group-hover:bg-primary-100 group-hover:hover:text-primary-800 group-hover:ring-secondary-500 group-active:bg-primary-200 group-active:text-primary-900 group-active:ring-secondary-600 group-has-[:focus-visible]:outline group-has-[:focus-visible]:outline-offset pointer-events-none"
tabindex="-1"
variant="secondary"
>
{{ buttonText }}
</SfButton>
</div>
<div class="absolute inset-0 z-[-1] overflow-hidden bg-primary-900">
<img :src="backgroundImage" :alt="title" class="w-full h-full object-cover opacity-75" />
</div>
</div>
</div>
</div>
</template>
<script lang="ts" setup>
import { SfButton } from '@storefront-ui/vue';
const displayDetails = [
{
title: 'Cap Game Strong',
subtitle: 'Special Offer',
description: 'Score serious style points with our Open Capsule collection',
buttonText: 'Browse offers',
backgroundImage: 'https://storage.googleapis.com/sfui_docs_artifacts_bucket_public/production/display-overlay.png',
},
];
</script>
Hero
The Hero block simplifies the process of creating stunning hero sections for your website. With Hero, you have the flexibility to seamlessly integrate a main image and customize your content to suit your needs. Additionally, Hero allows adding background images tailored for both mobile and desktop devices. To ensure an optimal blend of performance and visual appeal, we recommend adhering to the following image guidelines:
Desktop Background Images: Aspect ratio: 2:1 Example size: 2160 x 1080px
Mobile Background Images: Aspect ratio: 2:5 Example size: 420 x 1050px
<template>
<div class="relative h-dvh w-dvw shrink-0">
<picture>
<source :srcset="backgroundImage" media="(min-width: 768px)" />
<img :src="backgroundImageMobile" class="absolute w-full h-full z-[-1] object-cover" alt="hero" />
</picture>
<div
class="h-full w-full max-w-[1536px] mx-auto flex flex-col justify-end md:justify-center"
:class="variant === 'dark' ? 'text-white' : 'text-neutral-900'"
>
<div class="p-4 md:p-10 flex flex-col">
<p class="typography-text-xs md:typography-text-sm font-bold tracking-widest uppercase">
{{ headline }}
</p>
<h1 class="mt-2 mb-4 typography-display-2 md:typography-display-1 md:leading-[67.5px] font-bold">
{{ title }}
</h1>
<p class="typography-text-base md:typography-text-lg">
{{ description }}
</p>
<div class="mt-6 flex flex-col md:flex-row gap-4">
<SfButton size="lg" variant="secondary" class="bg-white">
{{ callToAction }}
</SfButton>
<SfButton size="lg">
{{ callToActionSecondary }}
</SfButton>
</div>
</div>
</div>
</div>
</template>
<script lang="ts" setup>
import { SfButton } from '@storefront-ui/vue';
const {
headline,
title,
description,
callToAction,
callToActionSecondary,
backgroundImage,
backgroundImageMobile,
image,
imageAlt,
variant,
} = {
headline: 'New collection',
title: 'Made to move. Built to win.',
description: 'The new sport collection is now in store.',
callToAction: 'Order now',
callToActionSecondary: 'Show more',
backgroundImage: 'https://storage.googleapis.com/sfui_docs_artifacts_bucket_public/production/hero-bg-2.png',
backgroundImageMobile: 'https://storage.googleapis.com/sfui_docs_artifacts_bucket_public/production/hero-bg-mobile-2.png',
image: undefined,
imageAlt: undefined,
variant: 'dark',
};
</script>
Hero With Side Image
Enhance your Hero section with a contextual image on the side.
<template>
<div class="relative h-dvh w-dvh shrink-0">
<picture>
<source :srcset="backgroundImage" media="(min-width: 768px)" />
<img :src="backgroundImageMobile" class="absolute w-full h-full z-[-1] object-cover" alt="hero" />
</picture>
<div
class="h-full w-full max-w-[1536px] mx-auto flex flex-col md:flex-row-reverse md:justify-center"
:class="variant === 'dark' ? 'text-white' : 'text-neutral-900'"
>
<div class="flex flex-col md:basis-2/4 md:items-stretch">
<img :src="image" :alt="imageAlt" class="h-full object-cover object-left overflow-visible" />
</div>
<div class="p-4 md:p-10 flex flex-col justify-center basis-2/4 md:items-start">
<p class="typography-text-xs md:typography-text-sm font-bold tracking-widest uppercase">
{{ headline }}
</p>
<h1 class="mt-2 mb-4 typography-display-2 md:typography-display-1 md:leading-[67.5px] font-bold">
{{ title }}
</h1>
<p class="typography-text-base md:typography-text-lg">
{{ description }}
</p>
<div class="mt-6 flex flex-col md:flex-row gap-4">
<SfButton size="lg">
{{ callToAction }}
</SfButton>
<SfButton size="lg" variant="secondary" class="bg-white">
{{ callToActionSecondary }}
</SfButton>
</div>
</div>
</div>
</div>
</template>
<script lang="ts" setup>
import { SfButton } from '@storefront-ui/vue';
const {
headline,
title,
description,
callToAction,
callToActionSecondary,
backgroundImage,
backgroundImageMobile,
image,
imageAlt,
variant,
} = {
headline: 'Feel the music',
title: 'New Wireless Pro',
description: 'Spatial audio. Adjustable ear cups. On-device controls. All-day battery.',
callToAction: 'Order now',
callToActionSecondary: 'Show more',
backgroundImage: 'https://storage.googleapis.com/sfui_docs_artifacts_bucket_public/production/hero-bg.png',
backgroundImageMobile: 'https://storage.googleapis.com/sfui_docs_artifacts_bucket_public/production/hero-bg-mobile.png',
image: 'https://storage.googleapis.com/sfui_docs_artifacts_bucket_public/production/hero-headphones.png',
imageAlt: 'Headphones',
variant: 'light',
};
</script>