import { Scrim, View, Text } from 'reshaped';
function Example() {
return (
<Scrim
position="bottom"
padding={4}
backgroundSlot={
<Image src="/hero.jpg" attributes={{ style: { objectFit: 'cover' } }} />
}
>
<View gap={2}>
<Text variant="title-4" color="white">Hero Title</Text>
<Text color="white">Description text over the scrim</Text>
</View>
</Scrim>
);
}
Scrim provides a darkened overlay container for displaying content over images or backgrounds. It’s commonly used for hero sections, cards with image backgrounds, and media overlays.
Content to display over the scrim.
Background content behind the scrim (typically an Image).<Scrim
backgroundSlot={
<Image src="/background.jpg" />
}
>
Position of the content over the scrim.Options: "full", "top", "bottom", "start", "end"Default: "full"<Scrim position="bottom"> {/* Content at bottom */}
<Scrim position="full"> {/* Content fills entire area */}
padding
number | Responsive<number>
Padding for the content. Inherited from View’s padding props.<Scrim padding={4}>
<Scrim padding={{ s: 3, m: 6 }}>
paddingInline
number | Responsive<number>
Horizontal padding for the content.
paddingBlock
number | Responsive<number>
Vertical padding for the content.
Border radius for the scrim container.Options: "small", "medium", "large", "full"<Scrim borderRadius="medium">
Additional CSS class for the root element.
Additional CSS class for the scrim overlay element.
Additional HTML attributes for the root element.
Examples
Basic Scrim
<Scrim
position="bottom"
padding={4}
backgroundSlot={
<Image
src="/hero-image.jpg"
attributes={{ style: { objectFit: 'cover', height: '400px' } }}
/>
}
>
<View gap={2}>
<Text variant="title-3" color="white">Welcome</Text>
<Text color="white">Get started with our platform</Text>
</View>
</Scrim>
Hero Section
function HeroSection() {
return (
<Scrim
position="full"
padding={8}
backgroundSlot={
<Image
src="/hero-background.jpg"
attributes={{
style: {
objectFit: 'cover',
width: '100%',
height: '600px',
},
}}
/>
}
>
<View height="100%" align="center" justify="center" gap={4}>
<Text variant="display-1" color="white" align="center">
Build Better Products
</Text>
<Text variant="title-5" color="white" align="center">
The complete toolkit for modern development
</Text>
<Button size="large" color="primary">
Get Started
</Button>
</View>
</Scrim>
);
}
Card with Image Background
function ImageCard({ title, description, image }) {
return (
<Scrim
position="bottom"
padding={4}
borderRadius="medium"
backgroundSlot={
<Image
src={image}
aspectRatio={16/9}
borderRadius="medium"
/>
}
>
<View gap={1}>
<Text variant="body-2" weight="bold" color="white">
{title}
</Text>
<Text variant="body-3" color="white">
{description}
</Text>
</View>
</Scrim>
);
}
Position Variants
<View gap={4}>
{/* Full coverage */}
<Scrim
position="full"
padding={4}
backgroundSlot={<Image src="/bg.jpg" />}
>
<View align="center" justify="center" height="100%">
<Text color="white">Centered content</Text>
</View>
</Scrim>
{/* Bottom position */}
<Scrim
position="bottom"
padding={4}
backgroundSlot={<Image src="/bg.jpg" />}
>
<Text color="white">Bottom aligned</Text>
</Scrim>
{/* Top position */}
<Scrim
position="top"
padding={4}
backgroundSlot={<Image src="/bg.jpg" />}
>
<Text color="white">Top aligned</Text>
</Scrim>
</View>
Product Showcase
function ProductCard({ product }) {
return (
<Scrim
position="bottom"
padding={3}
borderRadius="large"
backgroundSlot={
<Image
src={product.image}
aspectRatio={1}
borderRadius="large"
/>
}
>
<View gap={2}>
<View gap={1}>
<Text variant="body-2" weight="bold" color="white">
{product.name}
</Text>
<Text variant="body-3" color="white">
{product.category}
</Text>
</View>
<View direction="row" justify="space-between" align="center">
<Text variant="title-6" color="white">
${product.price}
</Text>
<Button size="small" color="white">
Add to Cart
</Button>
</View>
</View>
</Scrim>
);
}
Video Player Overlay
function VideoPlayer({ videoUrl, thumbnail }) {
const [playing, setPlaying] = React.useState(false);
return (
<Scrim
position="full"
borderRadius="medium"
backgroundSlot={
playing ? (
<video
src={videoUrl}
autoPlay
controls
style={{ width: '100%', height: '100%', objectFit: 'cover' }}
/>
) : (
<Image src={thumbnail} aspectRatio={16/9} />
)
}
>
{!playing && (
<View height="100%" align="center" justify="center">
<Button
icon={IconPlay}
variant="solid"
color="white"
size="large"
onClick={() => setPlaying(true)}
attributes={{ 'aria-label': 'Play video' }}
/>
</View>
)}
</Scrim>
);
}
Blog Post Card
function BlogPostCard({ post }) {
return (
<Scrim
position="bottom"
padding={4}
borderRadius="medium"
backgroundSlot={
<Image
src={post.coverImage}
aspectRatio={16/9}
borderRadius="medium"
/>
}
>
<View gap={2}>
<View direction="row" gap={2}>
<Badge color="white">{post.category}</Badge>
<Text variant="body-3" color="white">
{post.readTime} min read
</Text>
</View>
<Text variant="title-5" color="white">
{post.title}
</Text>
<Text variant="body-3" color="white">
{post.excerpt}
</Text>
<View direction="row" gap={2} align="center">
<Image
src={post.author.avatar}
width="32px"
height="32px"
borderRadius="full"
/>
<View gap={0}>
<Text variant="body-3" weight="bold" color="white">
{post.author.name}
</Text>
<Text variant="caption" color="white">
{post.publishedDate}
</Text>
</View>
</View>
</View>
</Scrim>
);
}
Responsive Padding
<Scrim
position="bottom"
padding={{ s: 3, m: 6 }}
paddingInline={{ s: 4, m: 8 }}
backgroundSlot={<Image src="/hero.jpg" />}
>
<Text variant="title-4" color="white">
Responsive content padding
</Text>
</Scrim>
Gallery Item
function GalleryItem({ image, title, likes, comments }) {
return (
<Scrim
position="bottom"
padding={3}
borderRadius="medium"
backgroundSlot={
<Image
src={image}
aspectRatio={1}
borderRadius="medium"
/>
}
>
<View gap={2}>
<Text variant="body-2" weight="bold" color="white">
{title}
</Text>
<View direction="row" gap={3}>
<View direction="row" gap={1} align="center">
<Icon svg={IconHeart} size="small" color="white" />
<Text variant="body-3" color="white">{likes}</Text>
</View>
<View direction="row" gap={1} align="center">
<Icon svg={IconMessage} size="small" color="white" />
<Text variant="body-3" color="white">{comments}</Text>
</View>
</View>
</View>
</Scrim>
);
}
Call-to-Action Banner
function CTABanner() {
return (
<Scrim
position="full"
padding={6}
borderRadius="large"
backgroundSlot={
<Image
src="/cta-background.jpg"
attributes={{
style: {
objectFit: 'cover',
width: '100%',
height: '300px',
},
}}
/>
}
>
<View height="100%" align="center" justify="center" gap={3}>
<Text variant="title-3" color="white" align="center">
Ready to get started?
</Text>
<Text variant="body-1" color="white" align="center">
Join thousands of teams building with our platform
</Text>
<View direction="row" gap={2}>
<Button size="large" color="white">
Start Free Trial
</Button>
<Button size="large" variant="outline" color="white">
Learn More
</Button>
</View>
</View>
</Scrim>
);
}
Accessibility
- Ensure adequate contrast between text and scrim overlay
- Use semantic HTML for content structure
- Provide alt text for background images via the Image component
- Test readability with different background images
- Consider users with reduced transparency preferences