
Syncfusion React Cards
- 350 installs
- 3 repo stars
- Updated July 28, 2026
- syncfusion/react-ui-components-skills
Use syncfusion-react-cards for development tasks
About
syncfusion-react-cards: A skill for development. This provides functionality for development workflows.
- syncfusion-react-cards
Syncfusion React Cards by the numbers
- 350 all-time installs (skills.sh)
- +53 installs in the week ending Aug 5, 2026 (Skillselion tracking)
- Ranked #1,197 of 4,347 Backend & APIs skills by installs in the Skillselion catalog
- Data as of Aug 5, 2026 (Skillselion catalog sync)
npx skills add https://github.com/syncfusion/react-ui-components-skills --skill syncfusion-react-cardsAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 350 |
|---|---|
| repo stars | ★ 3 |
| Last updated | July 28, 2026 |
| Repository | syncfusion/react-ui-components-skills ↗ |
What it does
Use syncfusion-react-cards for development tasks
Files
Implementing React Card Component
The Syncfusion React Card component is a lightweight, flexible container for displaying organized content with support for headers, images, dividers, action buttons, and integrated components.
When to Use This Skill
Use this skill when you need to:
- Create simple or complex card-based layouts
- Build a card with header, image, and action sections
- Display content in a card with separators or dividers
- Add action buttons (horizontal or vertical) to cards
- Create horizontal card layouts with stacked content
- Embed other Syncfusion components (ListView, Charts, etc.) inside cards
- Customize card appearance with images, titles, and positioning
- Build responsive card-based user interfaces
Navigation Guide
Follow this guide based on what you're implementing:
Getting Started
📄 Read: references/getting-started.md
- Package installation and setup
- Basic card structure and CSS imports
- Simple card examples
- Required dependencies
Card Structure & Headers
📄 Read: references/card-structure-headers.md
- Card root element and classes
- Header structure with title and subtitle
- Header images and positioning
- Content sections and organization
Images, Titles & Dividers
📄 Read: references/images-titles-dividers.md
- Adding images to cards
- Image titles and overlay effects
- Dividers for section separation
- Title positioning and customization
Action Buttons
📄 Read: references/action-buttons.md
- Adding buttons and links to cards
- Horizontal button layout (default)
- Vertical button alignment
- Icon buttons and styling
Layouts & Advanced
📄 Read: references/layouts-customization.md
- Horizontal card layout
- Stacked sections within cards
- Image title position classes
- CSS positioning and styling
Embedding Components
📄 Read: references/embedding-components.md
- Integrating ListView with cards
- Embedding charts and data components
- Dynamic content patterns
- Practical use cases
Quick Start Example
Basic Card with Header and Content:
import React from 'react';
import '@syncfusion/ej2-layouts/styles/tailwind3.css';
export default function BasicCard() {
return (
<div className="e-card">
<div className="e-card-header">
<div className="e-card-header-caption">
<div className="e-card-header-title">Card Title</div>
<div className="e-card-sub-title">Subtitle</div>
</div>
</div>
<div className="e-card-content">
This is the main content of the card. Add any HTML content here.
</div>
</div>
);
}Card with Action Buttons:
import React from 'react';
export default function CardWithButtons() {
return (
<div className="e-card">
<div className="e-card-header-title">Product Card</div>
<div className="e-card-content">
High-quality product description goes here.
</div>
<div className="e-card-actions">
<button className="e-card-btn">View</button>
<button className="e-card-btn">Buy Now</button>
<button className="e-card-btn">Share</button>
</div>
</div>
);
}Horizontal Layout Card:
import React from 'react';
export default function HorizontalCard() {
return (
<div className="e-card e-card-horizontal" style={{ width: '400px' }}>
<img src="./image.png" alt="Card" style={{ height: '180px' }} />
<div className="e-card-stacked">
<div className="e-card-header">
<div className="e-card-header-caption">
<div className="e-card-header-title">Title</div>
</div>
</div>
<div className="e-card-content">
Content displayed vertically within horizontal layout
</div>
</div>
</div>
);
}Common Patterns
Pattern 1: User Profile Card
Combine header images, titles, and action buttons to create profile cards for user listings or team pages.
<div className="e-card">
<div className="e-card-header">
<div className="e-card-header-image" style={{ backgroundImage: 'url(./profile.jpg)', width: '60px', height: '60px', borderRadius: '50%' }} />
<div className="e-card-header-caption">
<div className="e-card-header-title">John Doe</div>
<div className="e-card-sub-title">Product Manager</div>
</div>
</div>
<div className="e-card-content">
Experienced in building user-centric products.
</div>
<div className="e-card-actions">
<button className="e-card-btn">Message</button>
<button className="e-card-btn">Follow</button>
</div>
</div>Pattern 2: Product Card with Image
Use card images and titles for product listings with pricing and action buttons.
<div className="e-card">
<div className="e-card-image" style={{ backgroundImage: 'url(./product.jpg)', height: '200px' }}>
<div className="e-card-title">Product Name</div>
</div>
<div className="e-card-content">
<p>$99.99</p>
<p>High-quality product with excellent features</p>
</div>
<div className="e-card-actions">
<button className="e-card-btn">Add to Cart</button>
<button className="e-card-btn">Buy Now</button>
</div>
</div>Pattern 3: Blog Post Card
Combine headers, dividers, and content sections to create blog post cards.
<div className="e-card">
<div className="e-card-header-title">Blog Post Title</div>
<div className="e-card-sub-title">Published on March 26, 2026</div>
<div className="e-card-separator" />
<div className="e-card-content">
Blog post excerpt and content goes here...
</div>
<div className="e-card-actions">
<button className="e-card-btn">Read More</button>
<button className="e-card-btn">Share</button>
</div>
</div>Key CSS Classes
| Class | Purpose |
|---|---|
e-card | Root container for the card |
e-card-header | Header section container |
e-card-header-caption | Wrapper for title and subtitle |
e-card-header-title | Main title text |
e-card-sub-title | Subtitle text |
e-card-header-image | Header image element |
e-card-image | Full-width card image |
e-card-title | Title overlay on image |
e-card-content | Main content section |
e-card-actions | Button container |
e-card-btn | Individual button styling |
e-card-vertical | Vertical button alignment |
e-card-separator | Divider element |
e-card-horizontal | Horizontal card layout |
e-card-stacked | Vertical stack within horizontal |
e-card-corner | Rounded corners on images |
Essential Setup
1. Install package:
npm install @syncfusion/ej2-layouts2. Import CSS:
@import '@syncfusion/ej2-layouts/styles/tailwind3.css';3. Create card element:
- Add
e-cardclass to root div - Add header, content, images, or buttons as needed
- Apply additional classes for layout and styling
Common Use Cases
- Dashboard cards: Display key metrics or data summaries
- Product listings: Showcase products with images and prices
- Team members: Display user profiles and contact info
- Blog posts: Show article previews with meta information
- Feature highlights: Present features with descriptions
- Data reports: Organize tabular or list data in cards
- Notification cards: Display alerts or messages
- Settings cards: Group related settings together
---
Next Steps: Choose a reference based on your specific need, then implement your card layout following the examples and patterns provided.
Action Buttons
Adding Action Buttons
Action buttons allow users to interact with card content. They are organized in an action container at the bottom of the card.
Basic Button Structure
Action buttons are contained within a div with the e-card-actions class:
<div className="e-card">
<div className="e-card-content">
Card content
</div>
<div className="e-card-actions">
<button className="e-card-btn">Button 1</button>
<button className="e-card-btn">Button 2</button>
</div>
</div>Button and Link Elements
Use both button and anchor elements with the e-card-btn class:
<div className="e-card-actions">
<button className="e-card-btn">Action Button</button>
<a href="#" className="e-card-btn">Link Button</a>
</div>Multiple Action Buttons
<div className="e-card-actions">
<button className="e-card-btn">View</button>
<button className="e-card-btn">Edit</button>
<button className="e-card-btn">Delete</button>
</div>Horizontal Layout (Default)
By default, action buttons are positioned horizontally from left to right:
export default function HorizontalButtonsCard() {
return (
<div className="e-card" style={{ maxWidth: '300px' }}>
<div className="e-card-header-title">Product Name</div>
<div className="e-card-content">
High-quality product with excellent features.
</div>
<div className="e-card-actions">
<button className="e-card-btn">View</button>
<button className="e-card-btn">Add to Cart</button>
<button className="e-card-btn">Share</button>
</div>
</div>
);
}Output: Buttons displayed side-by-side from left to right.
Vertical Layout
Add the e-card-vertical class to the actions container to stack buttons vertically:
<div className="e-card-actions e-card-vertical">
<button className="e-card-btn">More</button>
<a href="#" className="e-card-btn">Share</a>
<button className="e-card-btn">Archive</button>
</div>Complete Vertical Buttons Card
export default function VerticalButtonsCard() {
return (
<div className="e-card" style={{ maxWidth: '300px' }}>
<div className="e-card-header-title">Eiffel Tower</div>
<div className="e-card-content">
The Eiffel Tower is acknowledged as the universal symbol of Paris and France.
</div>
<div className="e-card-actions e-card-vertical">
<button className="e-card-btn">More</button>
<a href="#" className="e-card-btn">Share</a>
<button className="e-card-btn">Save</button>
</div>
</div>
);
}Icon Buttons
Icon with Text
<div className="e-card-actions">
<button className="e-card-btn">
<span>📌</span> Bookmark
</button>
<button className="e-card-btn">
<span>❤️</span> Like
</button>
<button className="e-card-btn">
<span>🔗</span> Share
</button>
</div>Icon Only Buttons
<div className="e-card-actions">
<button className="e-card-btn" title="Bookmark">📌</button>
<button className="e-card-btn" title="Like">❤️</button>
<button className="e-card-btn" title="Share">🔗</button>
</div>Using Image Icons
<div className="e-card-actions">
<button className="e-card-btn">
<img src='./bookmark.png' alt="Bookmark" style={{ width: '20px' }} />
</button>
<button className="e-card-btn">
<img src='./like.png' alt="Like" style={{ width: '20px' }} />
</button>
<button className="e-card-btn">
<img src='./share.png' alt="Share" style={{ width: '20px' }} />
</button>
</div>Button Styling
Custom Button Styling
Style buttons with inline CSS or CSS classes:
<button className="e-card-btn"
style={{
padding: '10px 20px',
fontSize: '14px',
fontWeight: 'bold',
borderRadius: '4px'
}}>
Custom Button
</button>Primary and Secondary Buttons
<div className="e-card-actions">
<button className="e-card-btn"
style={{
background: '#007bff',
color: 'white',
border: 'none',
padding: '8px 16px'
}}>
Primary
</button>
<button className="e-card-btn"
style={{
background: '#e9ecef',
color: '#333',
border: 'none',
padding: '8px 16px'
}}>
Secondary
</button>
</div>Disabled Buttons
<button className="e-card-btn"
disabled
style={{
opacity: 0.5,
cursor: 'not-allowed'
}}>
Disabled Button
</button>Interactive Button Examples
Example 1: E-Commerce Card
export default function ProductCard() {
const [inCart, setInCart] = React.useState(false);
return (
<div className="e-card" style={{ maxWidth: '280px' }}>
<div className="e-card-image"
style={{
backgroundImage: 'url(./product.jpg)',
height: '200px'
}}>
<div className="e-card-title e-card-top-right">
Sale
</div>
</div>
<div className="e-card-header-title">Wireless Headphones</div>
<div className="e-card-sub-title">$99.99</div>
<div className="e-card-content">
<p>Premium sound quality with noise cancellation</p>
</div>
<div className="e-card-actions">
<button className="e-card-btn"
onClick={() => setInCart(!inCart)}
style={{
background: inCart ? '#dc3545' : '#28a745',
color: 'white',
flex: 1
}}>
{inCart ? 'Remove' : 'Add to Cart'}
</button>
<button className="e-card-btn"
style={{
background: '#6c757d',
color: 'white'
}}>
❤️
</button>
</div>
</div>
);
}Example 2: Team Member Card
export default function TeamMemberCard() {
const [expanded, setExpanded] = React.useState(false);
return (
<div className="e-card">
<div className="e-card-header">
<div className="e-card-header-image e-card-corner"
style={{
backgroundImage: 'url(./avatar.jpg)',
width: '80px',
height: '80px'
}} />
<div className="e-card-header-caption">
<div className="e-card-header-title">Sarah Johnson</div>
<div className="e-card-sub-title">Product Designer</div>
</div>
</div>
<div className="e-card-content">
<p>10+ years of experience in UX/UI design</p>
{expanded && <p>Email: sarah@company.com | Phone: +1-234-567-8900</p>}
</div>
<div className="e-card-actions">
<button className="e-card-btn"
onClick={() => setExpanded(!expanded)}>
{expanded ? 'Less Info' : 'More Info'}
</button>
<a href="#" className="e-card-btn">Message</a>
<a href="#" className="e-card-btn">Connect</a>
</div>
</div>
);
}Example 3: Settings Card
export default function SettingsCard() {
const [notifications, setNotifications] = React.useState(true);
return (
<div className="e-card">
<div className="e-card-header-title">Notification Settings</div>
<div className="e-card-separator" />
<div className="e-card-content">
<label>
<input type="checkbox"
checked={notifications}
onChange={(e) => setNotifications(e.target.checked)} />
Enable notifications
</label>
</div>
<div className="e-card-separator" />
<div className="e-card-actions e-card-vertical">
<button className="e-card-btn"
style={{
background: '#007bff',
color: 'white',
padding: '10px'
}}>
Save Settings
</button>
<button className="e-card-btn"
style={{
background: '#e9ecef',
padding: '10px'
}}>
Reset
</button>
</div>
</div>
);
}Best Practices
1. Limit buttons: Keep 2-4 action buttons per card for clarity
2. Clear labels: Use descriptive button text (avoid "Click here")
3. Consistent styling: Maintain consistent button appearance across cards
4. Logical order: Place primary actions (e.g., "Buy Now") first
5. Visual hierarchy: Use color and styling to highlight important actions
6. Responsive spacing: Buttons should have adequate spacing on mobile devices
7. Accessibility: Use semantic HTML (<button> or <a>) with descriptive labels
CSS Classes Reference
| Class | Purpose |
|---|---|
e-card-actions | Action button container |
e-card-btn | Individual button styling |
e-card-vertical | Vertical button alignment |
Next: Learn about layouts and customization for horizontal card layouts and advanced positioning.
Card Structure & Headers
Table of Contents
Header Organization
The card header provides a consistent area for displaying introductory information like titles, subtitles, and images.
Header Container
The e-card-header class defines the header section. Inside it, use e-card-header-caption to group text content:
<div className="e-card">
<div className="e-card-header">
<div className="e-card-header-caption">
{/* Title and subtitle go here */}
</div>
</div>
</div>When to use headers:
- User profile cards (name and title)
- Blog posts (article title and date)
- Product cards (product name and category)
- Team member listings
- Contact cards
Title and Subtitle
Header Title
The e-card-header-title class displays the main heading:
<div className="e-card-header-caption">
<div className="e-card-header-title">Main Title</div>
</div>Header Subtitle
The e-card-sub-title class displays secondary text below the title:
<div className="e-card-header-caption">
<div className="e-card-header-title">Primary Title</div>
<div className="e-card-sub-title">Secondary information</div>
</div>Complete Title Block
<div className="e-card">
<div className="e-card-header">
<div className="e-card-header-caption">
<div className="e-card-header-title">Laura Callahan</div>
<div className="e-card-sub-title">Sales Coordinator</div>
</div>
</div>
<div className="e-card-content">
Laura received a BA in psychology from the University of Washington.
</div>
</div>Header Images
Adding Header Images
Use the e-card-header-image class to include an image in the header. The image can be positioned before or after the caption text:
<div className="e-card-header">
<div className="e-card-header-image" />
<div className="e-card-header-caption">
<div className="e-card-header-title">Title</div>
</div>
</div>Image Positioning
Image before caption (left-aligned):
<div className="e-card">
<div className="e-card-header">
<div className="e-card-header-image" style={{ backgroundImage: 'url(./profile.jpg)' }} />
<div className="e-card-header-caption">
<div className="e-card-header-title">Name</div>
<div className="e-card-sub-title">Role</div>
</div>
</div>
</div>Image after caption (right-aligned):
<div className="e-card">
<div className="e-card-header">
<div className="e-card-header-caption">
<div className="e-card-header-title">Name</div>
<div className="e-card-sub-title">Role</div>
</div>
<div className="e-card-header-image" style={{ backgroundImage: 'url(./profile.jpg)' }} />
</div>
</div>Rounded Corner Images
Add the e-card-corner class to create rounded corner images:
<div className="e-card-header-image e-card-corner"
style={{ backgroundImage: 'url(./avatar.jpg)' }} />Image Sizing
Style the header image with width and height:
<div className="e-card-header-image e-card-corner"
style={{
backgroundImage: 'url(./avatar.jpg)',
width: '60px',
height: '60px',
backgroundSize: 'cover',
backgroundPosition: 'center'
}} />Content Organization
Content Section
The e-card-content class holds the main body of the card:
<div className="e-card-content">
Main content goes here. This can include text, links, forms, or other HTML elements.
</div>Multiple Content Sections
You can add multiple content sections separated by dividers:
<div className="e-card">
<div className="e-card-title">Explore Cities</div>
<div className="e-card-separator" />
<div className="e-card-content">
Sydney is a city on the east coast of Australia...
</div>
<div className="e-card-separator" />
<div className="e-card-content">
New York City has been described as the cultural capital...
</div>
</div>Content Flexibility
Content sections accept any HTML:
<div className="e-card-content">
<h3>Section Title</h3>
<p>Paragraph text</p>
<ul>
<li>List item 1</li>
<li>List item 2</li>
</ul>
<a href="#">Link</a>
</div>Complete Examples
Example 1: Professional Profile Card
export default function ProfileCard() {
return (
<div className="e-card">
<div className="e-card-header">
<div className="e-card-header-image e-card-corner"
style={{
backgroundImage: 'url(./profile.jpg)',
width: '80px',
height: '80px'
}} />
<div className="e-card-header-caption">
<div className="e-card-header-title">John Smith</div>
<div className="e-card-sub-title">Senior Developer</div>
</div>
</div>
<div className="e-card-content">
<p>10+ years of experience in web development</p>
<p>Specializing in React and modern JavaScript</p>
</div>
</div>
);
}Example 2: Blog Article Card
export default function BlogCard() {
return (
<div className="e-card">
<div className="e-card-header">
<div className="e-card-header-caption">
<div className="e-card-header-title">
Getting Started with React Hooks
</div>
<div className="e-card-sub-title">
Published March 26, 2026 by John Doe
</div>
</div>
</div>
<div className="e-card-content">
<p>React Hooks allow you to use state and other React features without writing a class component...</p>
</div>
</div>
);
}Example 3: Product Header Card
export default function ProductCard() {
return (
<div className="e-card">
<div className="e-card-header">
<div className="e-card-header-image"
style={{
backgroundImage: 'url(./product.jpg)',
height: '120px'
}} />
<div className="e-card-header-caption">
<div className="e-card-header-title">Premium Headphones</div>
<div className="e-card-sub-title">Audio Excellence Series</div>
</div>
</div>
<div className="e-card-content">
<p><strong>$199.99</strong></p>
<p>High-quality sound with noise cancellation</p>
</div>
</div>
);
}Key CSS Classes
| Class | Purpose |
|---|---|
e-card-header | Header container |
e-card-header-caption | Text content wrapper |
e-card-header-title | Main title |
e-card-header-image | Header image |
e-card-sub-title | Subtitle text |
e-card-corner | Rounded corners for images |
e-card-content | Content area |
e-card-separator | Divider line |
Tips & Best Practices
1. Always wrap title/subtitle in caption: The e-card-header-caption provides proper spacing and alignment
2. Use semantic HTML: Include proper heading levels (h1, h2, h3) within content sections for accessibility
3. Image optimization: Use appropriately sized images and set explicit width/height to prevent layout shift
4. Responsive design: Use percentage widths and max-widths for responsive cards
5. Spacing: Let CSS handle alignment; the framework provides default spacing
Next: Learn about images, titles, and dividers for full-width card images and advanced layouts.
Embedding Components in Cards
The Card component provides a flexible container that can host any other component within its content area, enabling the creation of rich, interactive interfaces. By combining the structured layout benefits of cards with the functionality of other Syncfusion components, you can build sophisticated UIs.
Basic Component Integration
Simple Component Embedding
Any React component can be placed inside the card's content section:
import React from 'react';
import { ListViewComponent } from '@syncfusion/ej2-react-lists';
export default function CardWithList() {
const todoList = [
{ todoList: 'Pay Bills' },
{ todoList: 'Call Chris' },
{ todoList: 'Meet Andrew' }
];
const fields = { text: 'todoList' };
return (
<div className="e-card">
<div className="e-card-title">To-Do List</div>
<div className="e-card-separator" />
<div className="e-card-content">
<ListViewComponent
dataSource={todoList}
fields={fields}
showCheckBox={true} />
</div>
</div>
);
}Component with Header
<div className="e-card">
<div className="e-card-header">
<div className="e-card-header-caption">
<div className="e-card-header-title">Component Header</div>
<div className="e-card-sub-title">Embedded within card</div>
</div>
</div>
<div className="e-card-separator" />
<div className="e-card-content">
<YourComponentHere />
</div>
</div>ListView Integration
To-Do List Card
import { ListViewComponent } from '@syncfusion/ej2-react-lists';
export default function TodoCard() {
const todoList = [
{ todoList: 'Pay Bills' },
{ todoList: 'Call Chris' },
{ todoList: 'Meet Andrew' },
{ todoList: 'Visit Manager' },
{ todoList: 'Customer Meeting' }
];
const fields = { text: 'todoList' };
return (
<div className="e-card">
<div className="e-card-title">To-Do List</div>
<div className="e-card-separator" />
<div className="e-card-content">
<ListViewComponent
dataSource={todoList}
fields={fields}
showCheckBox={true} />
</div>
</div>
);
}Output: A card containing an interactive to-do list with checkboxes.
Advanced ListView Card
import React, { useState } from 'react';
import { ListViewComponent } from '@syncfusion/ej2-react-lists';
export default function AdvancedListCard() {
const [items, setItems] = useState([
{ id: 1, text: 'Pending Task 1', status: 'pending' },
{ id: 2, text: 'Pending Task 2', status: 'pending' },
{ id: 3, text: 'Completed Task 1', status: 'completed' }
]);
const fields = { text: 'text' };
const onSelect = (args) => {
console.log('Selected item:', args.data);
};
return (
<div className="e-card" style={{ maxWidth: '400px' }}>
<div className="e-card-header">
<div className="e-card-header-caption">
<div className="e-card-header-title">Project Tasks</div>
<div className="e-card-sub-title">{items.length} items</div>
</div>
</div>
<div className="e-card-separator" />
<div className="e-card-content">
<ListViewComponent
dataSource={items}
fields={fields}
select={onSelect}
showCheckBox={true} />
</div>
<div className="e-card-actions">
<button className="e-card-btn">Add Task</button>
<button className="e-card-btn">Clear Completed</button>
</div>
</div>
);
}Other Component Integration
Card with Data Grid
import { GridComponent, ColumnsDirective, ColumnDirective, Inject, Page, Sort, Filter } from '@syncfusion/ej2-react-grids';
export default function CardWithGrid() {
const data = [
{ OrderID: 10248, CustomerName: 'VINET', TotalAmount: 32.38 },
{ OrderID: 10249, CustomerName: 'TOMSP', TotalAmount: 11.61 },
{ OrderID: 10250, CustomerName: 'HANAR', TotalAmount: 65.83 }
];
return (
<div className="e-card">
<div className="e-card-header-title">Sales Data</div>
<div className="e-card-separator" />
<div className="e-card-content">
<GridComponent dataSource={data} allowPaging={true} pageSettings={{ pageSize: 5 }}>
<ColumnsDirective>
<ColumnDirective field='OrderID' headerText='Order ID' width='100' />
<ColumnDirective field='CustomerName' headerText='Customer' width='150' />
<ColumnDirective field='TotalAmount' headerText='Amount' width='100' />
</ColumnsDirective>
<Inject services={[Page, Sort, Filter]} />
</GridComponent>
</div>
</div>
);
}Card with Chart
import { ChartComponent, SeriesCollectionDirective, SeriesDirective, Inject, LineSeries, DateTime, Legend, Tooltip } from '@syncfusion/ej2-react-charts';
export default function CardWithChart() {
const data = [
{ x: new Date(2024, 0, 1), yValue: 21 },
{ x: new Date(2024, 1, 1), yValue: 24 },
{ x: new Date(2024, 2, 1), yValue: 36 },
{ x: new Date(2024, 3, 1), yValue: 38 }
];
return (
<div className="e-card">
<div className="e-card-header-title">Sales Trend</div>
<div className="e-card-separator" />
<div className="e-card-content">
<ChartComponent>
<SeriesCollectionDirective>
<SeriesDirective dataSource={data} xName='x' yName='yValue' type='Line' />
</SeriesCollectionDirective>
<Inject services={[LineSeries, DateTime, Legend, Tooltip]} />
</ChartComponent>
</div>
</div>
);
}Card with Buttons Component
import { ButtonComponent } from '@syncfusion/ej2-react-buttons';
export default function CardWithButtons() {
return (
<div className="e-card">
<div className="e-card-header-title">Settings</div>
<div className="e-card-separator" />
<div className="e-card-content" style={{ display: 'flex', flexDirection: 'column', gap: '10px' }}>
<ButtonComponent className='e-primary'>Save Changes</ButtonComponent>
<ButtonComponent className='e-outline'>Cancel</ButtonComponent>
</div>
</div>
);
}Card with Dropdown
import { DropDownListComponent } from '@syncfusion/ej2-react-dropdowns';
export default function CardWithDropdown() {
const countries = [
{ text: 'United States', value: 'USA' },
{ text: 'Canada', value: 'CAN' },
{ text: 'United Kingdom', value: 'UK' },
{ text: 'Australia', value: 'AUS' }
];
const fields = { text: 'text', value: 'value' };
return (
<div className="e-card">
<div className="e-card-header-title">Select Country</div>
<div className="e-card-separator" />
<div className="e-card-content">
<DropDownListComponent
dataSource={countries}
fields={fields}
placeholder="Choose a country"
width="100%" />
</div>
</div>
);
}Dynamic Content Patterns
Card with State Management
import React, { useState } from 'react';
import { ListViewComponent } from '@syncfusion/ej2-react-lists';
export default function DynamicCard() {
const [items, setItems] = useState([
{ id: 1, name: 'Item 1' },
{ id: 2, name: 'Item 2' }
]);
const [newItem, setNewItem] = useState('');
const addItem = () => {
if (newItem.trim()) {
setItems([...items, { id: items.length + 1, name: newItem }]);
setNewItem('');
}
};
const fields = { text: 'name' };
return (
<div className="e-card">
<div className="e-card-header-title">Dynamic List</div>
<div className="e-card-separator" />
<div className="e-card-content">
<ListViewComponent
dataSource={items}
fields={fields} />
</div>
<div className="e-card-separator" />
<div className="e-card-content">
<div style={{ display: 'flex', gap: '5px' }}>
<input
type="text"
value={newItem}
onChange={(e) => setNewItem(e.target.value)}
placeholder="Add new item"
style={{ flex: 1, padding: '8px', borderRadius: '4px', border: '1px solid #ccc' }} />
<button
onClick={addItem}
style={{ padding: '8px 16px', background: '#007bff', color: 'white', border: 'none', borderRadius: '4px', cursor: 'pointer' }}>
Add
</button>
</div>
</div>
</div>
);
}Card with Conditional Content
import React, { useState } from 'react';
export default function ConditionalCard() {
const [expanded, setExpanded] = useState(false);
const [selectedTab, setSelectedTab] = useState('overview');
return (
<div className="e-card">
<div className="e-card-header-title">Content Switcher</div>
<div className="e-card-separator" />
<div className="e-card-content">
<div style={{ display: 'flex', gap: '10px', marginBottom: '15px' }}>
<button
onClick={() => setSelectedTab('overview')}
style={{
padding: '8px 12px',
background: selectedTab === 'overview' ? '#007bff' : '#e9ecef',
color: selectedTab === 'overview' ? 'white' : 'black',
border: 'none',
borderRadius: '4px',
cursor: 'pointer'
}}>
Overview
</button>
<button
onClick={() => setSelectedTab('details')}
style={{
padding: '8px 12px',
background: selectedTab === 'details' ? '#007bff' : '#e9ecef',
color: selectedTab === 'details' ? 'white' : 'black',
border: 'none',
borderRadius: '4px',
cursor: 'pointer'
}}>
Details
</button>
</div>
</div>
<div className="e-card-separator" />
<div className="e-card-content">
{selectedTab === 'overview' && (
<div>
<h3>Overview</h3>
<p>General information about the item</p>
</div>
)}
{selectedTab === 'details' && (
<div>
<h3>Details</h3>
<p>Detailed specification and information</p>
</div>
)}
</div>
</div>
);
}Use Cases
Dashboard Widget Card
Combine charts, grids, and metrics in a single card:
export default function DashboardCard() {
return (
<div className="e-card">
<div className="e-card-header-title">Sales Dashboard</div>
<div className="e-card-separator" />
<div className="e-card-content">
<div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: '10px', marginBottom: '15px' }}>
<div style={{ padding: '10px', background: '#f0f0f0', borderRadius: '4px' }}>
<p style={{ margin: '0 0 5px 0', fontSize: '12px', color: '#666' }}>Total Sales</p>
<h3 style={{ margin: 0 }}>$45,290</h3>
</div>
<div style={{ padding: '10px', background: '#f0f0f0', borderRadius: '4px' }}>
<p style={{ margin: '0 0 5px 0', fontSize: '12px', color: '#666' }}>Growth</p>
<h3 style={{ margin: 0, color: '#28a745' }}>+12.5%</h3>
</div>
</div>
{/* Chart component would go here */}
</div>
</div>
);
}Form Card
Combine form elements with validation:
export default function FormCard() {
const [formData, setFormData] = React.useState({ name: '', email: '' });
const handleChange = (e) => {
setFormData({ ...formData, [e.target.name]: e.target.value });
};
const handleSubmit = () => {
console.log('Form submitted:', formData);
};
return (
<div className="e-card">
<div className="e-card-header-title">Contact Form</div>
<div className="e-card-separator" />
<div className="e-card-content">
<input
type="text"
name="name"
placeholder="Your name"
value={formData.name}
onChange={handleChange}
style={{ width: '100%', padding: '8px', marginBottom: '10px', borderRadius: '4px', border: '1px solid #ccc', boxSizing: 'border-box' }} />
<input
type="email"
name="email"
placeholder="Your email"
value={formData.email}
onChange={handleChange}
style={{ width: '100%', padding: '8px', marginBottom: '10px', borderRadius: '4px', border: '1px solid #ccc', boxSizing: 'border-box' }} />
</div>
<div className="e-card-actions">
<button className="e-card-btn" onClick={handleSubmit}>Submit</button>
</div>
</div>
);
}Best Practices
1. Performance: Lazy load heavy components inside cards to improve initial render time
2. Data binding: Pass data to embedded components through props for maintainability
3. Event handling: Properly handle component events and communicate up/down the hierarchy
4. Responsive design: Ensure embedded components respond to card container width
5. Accessibility: Maintain semantic HTML and ARIA labels for embedded components
6. Styling: Consider card styling when embedding to maintain consistent appearance
7. Memory management: Clean up subscriptions and event listeners in useEffect cleanup
Return to: SKILL.md for navigation to other topics.
Getting Started with Card Component
Installation & Setup
Package Installation
Install the Syncfusion layouts package which contains the Card component:
npm install @syncfusion/ej2-layouts --saveImport CSS Styles
Add the Card CSS styles to your React application. Choose the theme that matches your design system:
/* Using Tailwind CSS theme (recommended) */
@import '@syncfusion/ej2-layouts/styles/tailwind3.css';
/* Or use other available themes: */
/* @import '@syncfusion/ej2-layouts/styles/bootstrap5.css'; */
/* @import '@syncfusion/ej2-layouts/styles/material.css'; */
/* @import '@syncfusion/ej2-layouts/styles/fluent.css'; */Place this import in your main CSS file or at the top of your component file.
Basic Card Structure
A Card component is built using HTML div elements with specific CSS classes. The Card is purely CSS-based—no JavaScript component instance is required.
Minimal Card
The simplest card requires just the root element:
<div className="e-card">
Sample Card Content
</div>Card with Sections
A typical card includes header, content, and optional footer:
<div className="e-card">
{/* Header section (optional) */}
<div className="e-card-header">
<div className="e-card-header-caption">
<div className="e-card-header-title">Header Title</div>
</div>
</div>
{/* Content section */}
<div className="e-card-content">
Card content goes here
</div>
{/* Actions section (optional) */}
<div className="e-card-actions">
<button className="e-card-btn">Action</button>
</div>
</div>Simple Examples
Example 1: Text-Only Card
import React from 'react';
import '@syncfusion/ej2-layouts/styles/tailwind3.css';
export default function SimpleCard() {
return (
<div className="e-card">
<div className="e-card-content">
This is a simple card with just text content. You can add any HTML elements inside.
</div>
</div>
);
}Example 2: Card with Title
export default function CardWithTitle() {
return (
<div className="e-card">
<div className="e-card-header-title">My Card Title</div>
<div className="e-card-content">
This card displays a title at the top.
</div>
</div>
);
}Example 3: Card with Header and Content
export default function CardWithHeader() {
return (
<div className="e-card">
<div className="e-card-header">
<div className="e-card-header-caption">
<div className="e-card-header-title">Professional Card</div>
<div className="e-card-sub-title">With subtitle</div>
</div>
</div>
<div className="e-card-content">
Well-organized card with a header section containing title and subtitle.
</div>
</div>
);
}CSS Classes Overview
Root Element
| Class | Purpose |
|---|---|
e-card | Main card container (required) |
e-card-horizontal | Makes card layout horizontal (optional) |
Header Section
| Class | Purpose |
|---|---|
e-card-header | Header container |
e-card-header-caption | Wrapper for text content in header |
e-card-header-title | Main title text |
e-card-sub-title | Subtitle text below title |
e-card-header-image | Image in header section |
Content Sections
| Class | Purpose |
|---|---|
e-card-content | Main content area |
e-card-image | Full-width image section |
e-card-title | Title overlay on images |
e-card-separator | Visual divider between sections |
Action Section
| Class | Purpose |
|---|---|
e-card-actions | Button container |
e-card-btn | Individual button styling |
e-card-vertical | Stack buttons vertically |
Important Notes
1. CSS-Based: The Card component is entirely CSS-based. No JavaScript initialization is needed.
2. Flexible Structure: You only need to include the sections you require. A card can have just content, or a full header with images and actions.
3. Theme Support: Choose a theme during import that matches your application's design system.
4. Responsive: Card layouts are responsive by default and adapt to container width.
5. Class Naming: All Card classes use the e-card prefix followed by the section name (e.g., e-card-header, e-card-content).
Common Patterns
Card with all sections:
<div className="e-card">
<div className="e-card-header">
<div className="e-card-header-caption">
<div className="e-card-header-title">Complete Card</div>
<div className="e-card-sub-title">With all sections</div>
</div>
</div>
<div className="e-card-content">
Main content area with detailed information
</div>
<div className="e-card-actions">
<button className="e-card-btn">Action 1</button>
<button className="e-card-btn">Action 2</button>
</div>
</div>Next: Read about card structure and headers to add more complex header layouts with images and captions.
Images, Titles & Dividers
Card Images
Full-Width Card Images
The e-card-image class creates a full-width image section that spans the entire width of the card:
<div className="e-card">
<div className="e-card-image"
style={{ backgroundImage: 'url(./image.jpg)', height: '200px' }} />
<div className="e-card-content">
Content below the image
</div>
</div>Key points:
- By default, card images occupy 100% of their parent element's width
- Set explicit height to control image display area
- Use CSS
backgroundImageproperty with background sizing
Image Styling
<div className="e-card-image"
style={{
backgroundImage: 'url(./photo.jpg)',
backgroundSize: 'cover',
backgroundPosition: 'center',
height: '250px'
}} />Image with Content Overlay
Position content over the image using absolute positioning:
<div style={{ position: 'relative' }}>
<div className="e-card-image"
style={{
backgroundImage: 'url(./background.jpg)',
height: '300px'
}} />
<div style={{
position: 'absolute',
bottom: '0',
left: '0',
right: '0',
padding: '20px',
background: 'rgba(0,0,0,0.5)',
color: 'white'
}}>
Overlay content here
</div>
</div>Image Titles
Basic Image Title
The e-card-title class displays a title overlay on top of card images. By default, titles appear in the bottom-left corner with an overlay effect:
<div className="e-card">
<div className="e-card-image"
style={{ backgroundImage: 'url(./image.jpg)', height: '200px' }}>
<div className="e-card-title">Image Title</div>
</div>
<div className="e-card-content">
Card content
</div>
</div>Title Positioning
By default, titles appear in the bottom-left position. Use positioning classes to change location:
{/* Bottom-left (default) */}
<div className="e-card-title e-card-bottom-left">Title</div>
{/* Bottom-right */}
<div className="e-card-title e-card-bottom-right">Title</div>
{/* Top-left */}
<div className="e-card-title e-card-top-left">Title</div>
{/* Top-right */}
<div className="e-card-title e-card-top-right">Title</div>Complete Image Title Example
export default function ImageTitleCard() {
return (
<div className="e-card">
<div className="e-card-image"
style={{
backgroundImage: 'url(./city.jpg)',
backgroundSize: 'cover',
backgroundPosition: 'center',
height: '250px'
}}>
<div className="e-card-title e-card-bottom-left">
Beautiful City
</div>
</div>
<div className="e-card-content">
<p>Stunning urban landscape photography</p>
</div>
</div>
);
}Customizing Title Appearance
Style the title with CSS:
<div className="e-card-image"
style={{ backgroundImage: 'url(./image.jpg)', height: '200px' }}>
<div className="e-card-title e-card-top-right"
style={{
fontSize: '24px',
fontWeight: 'bold',
padding: '15px',
textShadow: '2px 2px 4px rgba(0,0,0,0.7)'
}}>
Custom Title
</div>
</div>Interactive Title Position Selection
import React, { useState } from 'react';
export default function InteractiveTitleCard() {
const [position, setPosition] = useState('e-card-bottom-left');
const positions = [
{ value: 'e-card-bottom-left', label: 'Bottom-Left' },
{ value: 'e-card-bottom-right', label: 'Bottom-Right' },
{ value: 'e-card-top-left', label: 'Top-Left' },
{ value: 'e-card-top-right', label: 'Top-Right' }
];
return (
<div>
<div style={{ marginBottom: '20px' }}>
{positions.map(pos => (
<button
key={pos.value}
onClick={() => setPosition(pos.value)}
style={{
marginRight: '10px',
padding: '8px 12px',
cursor: 'pointer',
background: position === pos.value ? '#007bff' : '#e9ecef',
color: position === pos.value ? 'white' : 'black',
border: 'none',
borderRadius: '4px'
}}>
{pos.label}
</button>
))}
</div>
<div className="e-card">
<div className="e-card-image"
style={{
backgroundImage: 'url(./sample.jpg)',
height: '300px'
}}>
<div className={`e-card-title ${position}`}>
Image Title
</div>
</div>
</div>
</div>
);
}Dividers
Card Separator Element
The e-card-separator class creates a horizontal divider line between card sections:
<div className="e-card">
<div className="e-card-header-title">Section 1</div>
<div className="e-card-separator" />
<div className="e-card-content">
First content section
</div>
</div>Multiple Dividers
Use multiple dividers to create distinct content sections:
export default function MultiSectionCard() {
return (
<div className="e-card">
<div className="e-card-header-title">City Guide</div>
<div className="e-card-separator" />
<div className="e-card-content">
<h3>Sydney</h3>
<p>Sydney is a city on the east coast of Australia...</p>
</div>
<div className="e-card-separator" />
<div className="e-card-content">
<h3>New York</h3>
<p>New York City has been described as the cultural capital...</p>
</div>
<div className="e-card-separator" />
<div className="e-card-content">
<h3>London</h3>
<p>London is the capital and most populous city of England...</p>
</div>
</div>
);
}Divider with Images and Content
export default function RichDividedCard() {
return (
<div className="e-card">
<div className="e-card-image"
style={{
backgroundImage: 'url(./header.jpg)',
height: '150px'
}} />
<div className="e-card-separator" />
<div className="e-card-content">
<h2>Main Heading</h2>
<p>Important content goes here</p>
</div>
<div className="e-card-separator" />
<div className="e-card-content">
<h3>Additional Details</h3>
<ul>
<li>Detail point 1</li>
<li>Detail point 2</li>
<li>Detail point 3</li>
</ul>
</div>
</div>
);
}Title Position Classes Reference
| Class | Position |
|---|---|
e-card-bottom-left | Bottom-left corner (default) |
e-card-bottom-right | Bottom-right corner |
e-card-top-left | Top-left corner |
e-card-top-right | Top-right corner |
Common Patterns
Pattern 1: Gallery Card
<div className="e-card" style={{ maxWidth: '300px' }}>
<div className="e-card-image"
style={{
backgroundImage: 'url(./gallery.jpg)',
height: '250px'
}}>
<div className="e-card-title e-card-top-right">
Featured
</div>
</div>
<div className="e-card-separator" />
<div className="e-card-content">
<p>Beautiful sunset over the mountains</p>
</div>
</div>Pattern 2: Article Preview
<div className="e-card">
<div className="e-card-image"
style={{
backgroundImage: 'url(./article-header.jpg)',
height: '200px'
}}>
<div className="e-card-title e-card-bottom-left">
Technology
</div>
</div>
<div className="e-card-separator" />
<div className="e-card-content">
<h2>Article Title</h2>
<p>Article summary and excerpt...</p>
</div>
</div>Pattern 3: Feature Showcase
<div className="e-card">
<div className="e-card-header-title">Feature Name</div>
<div className="e-card-separator" />
<div className="e-card-image"
style={{
backgroundImage: 'url(./feature.jpg)',
height: '150px'
}} />
<div className="e-card-separator" />
<div className="e-card-content">
Feature description and details
</div>
</div>Tips & Best Practices
1. Use dividers sparingly: They organize content but too many can make a card feel cluttered
2. Consistent image heights: Keep image heights consistent across a grid of cards for better alignment
3. Title contrast: Ensure title text has sufficient contrast against background images (use textShadow if needed)
4. Image optimization: Compress images for better performance and faster loading
5. Responsive heights: Use percentage heights or viewport units for responsive layouts
Next: Learn about action buttons to add interactive elements to your cards.
Layouts & Customization
Table of Contents
- Horizontal Card Layout
- Stacked Sections
- Image Title Positioning
- Advanced Customization
- Responsive Patterns
Horizontal Card Layout
By default, card elements are stacked vertically following the natural DOM flow. The horizontal layout provides an alternative arrangement where elements are positioned side-by-side.
Basic Horizontal Layout
Add the e-card-horizontal class to the root card element:
<div className="e-card e-card-horizontal">
<img src="./image.png" alt="Sample" style={{ height: '180px' }} />
<div className="e-card-stacked">
<div className="e-card-header">
<div className="e-card-header-caption">
<div className="e-card-header-title">Title</div>
</div>
</div>
<div className="e-card-content">
Content arranged vertically within horizontal layout
</div>
</div>
</div>When to Use Horizontal Layout
- Product listings with image and details side-by-side
- Team member cards with photo and information
- Article previews with thumbnail and summary
- Blog post cards with featured image
- Settings or preference cards with icon and options
Complete Horizontal Layout Example
export default function HorizontalCard() {
return (
<div className="e-card e-card-horizontal" style={{ width: '400px', margin: '20px' }}>
<img src="./product.jpg" alt="Product"
style={{
width: '150px',
height: '150px',
objectFit: 'cover'
}} />
<div className="e-card-stacked">
<div className="e-card-header">
<div className="e-card-header-caption">
<div className="e-card-header-title">Philips Trimmer</div>
<div className="e-card-sub-title">Premium Quality</div>
</div>
</div>
<div className="e-card-content">
<p>Powered by innovative DuraPower Technology for long-lasting performance.</p>
<p style={{ fontSize: '14px', color: '#666' }}>4.5 ⭐ (320 reviews)</p>
</div>
<div className="e-card-actions">
<button className="e-card-btn" style={{ flex: 1 }}>View</button>
<button className="e-card-btn" style={{ flex: 1 }}>Buy Now</button>
</div>
</div>
</div>
);
}Stacked Sections
About Stacked Sections
The e-card-stacked class forces vertical alignment for specific sections within a horizontal layout. This is useful when you want part of your card to maintain the default vertical stacking while other parts are arranged horizontally.
Basic Stacked Example
<div className="e-card e-card-horizontal">
{/* First element - positioned horizontally */}
<img src="./image.jpg" alt="Featured" style={{ width: '200px', height: '150px' }} />
{/* Stacked section - content flows vertically */}
<div className="e-card-stacked">
<div className="e-card-header">
<div className="e-card-header-caption">
<div className="e-card-header-title">Feature Title</div>
</div>
</div>
<div className="e-card-content">First content block</div>
<div className="e-card-separator" />
<div className="e-card-content">Second content block</div>
</div>
</div>Multiple Content Sections in Stacked
export default function StackedSectionsCard() {
return (
<div className="e-card e-card-horizontal" style={{ width: '500px' }}>
<div style={{
background: 'linear-gradient(135deg, #667eea 0%, #764ba2 100%)',
width: '150px',
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
color: 'white',
fontSize: '48px'
}}>
📊
</div>
<div className="e-card-stacked" style={{ flex: 1 }}>
<div className="e-card-header-title">Analytics Report</div>
<div className="e-card-separator" />
<div className="e-card-content">
<h4>Performance Metrics</h4>
<p>Total Views: 12,450</p>
<p>Engagement Rate: 8.5%</p>
</div>
<div className="e-card-separator" />
<div className="e-card-content">
<h4>Key Insights</h4>
<ul style={{ margin: '8px 0', paddingLeft: '20px' }}>
<li>Peak hours: 2-4 PM</li>
<li>Top source: Organic search</li>
<li>Device: Mobile (65%)</li>
</ul>
</div>
</div>
</div>
);
}Image Title Positioning
Default Title Position
By default, image titles appear in the bottom-left corner with an overlay effect:
<div className="e-card-image" style={{ backgroundImage: 'url(./image.jpg)', height: '200px' }}>
<div className="e-card-title">Image Title</div>
</div>Position Classes
Use positioning classes to customize title location:
{/* Bottom-left (default) */}
<div className="e-card-title e-card-bottom-left">Title</div>
{/* Bottom-right */}
<div className="e-card-title e-card-bottom-right">Title</div>
{/* Top-left */}
<div className="e-card-title e-card-top-left">Title</div>
{/* Top-right */}
<div className="e-card-title e-card-top-right">Title</div>Complete Position Example
export default function TitlePositionCard() {
const [position, setPosition] = React.useState('e-card-bottom-left');
const positions = [
{ value: 'e-card-bottom-left', label: 'Bottom-Left' },
{ value: 'e-card-bottom-right', label: 'Bottom-Right' },
{ value: 'e-card-top-left', label: 'Top-Left' },
{ value: 'e-card-top-right', label: 'Top-Right' }
];
return (
<div>
<div style={{ marginBottom: '20px', display: 'flex', gap: '10px' }}>
{positions.map(pos => (
<button
key={pos.value}
onClick={() => setPosition(pos.value)}
style={{
padding: '8px 12px',
cursor: 'pointer',
background: position === pos.value ? '#007bff' : '#e9ecef',
color: position === pos.value ? 'white' : 'black',
border: 'none',
borderRadius: '4px'
}}>
{pos.label}
</button>
))}
</div>
<div className="e-card" style={{ maxWidth: '300px' }}>
<div className="e-card-image"
style={{
backgroundImage: 'url(./scenic.jpg)',
backgroundSize: 'cover',
backgroundPosition: 'center',
height: '250px'
}}>
<div className={`e-card-title ${position}`}
style={{
fontSize: '18px',
fontWeight: 'bold',
padding: '10px'
}}>
Mountain View
</div>
</div>
</div>
</div>
);
}Customizing Position Styles
Override default positioning with CSS:
<style>{`
.e-card-title.custom-position {
top: 50% !important;
left: 50% !important;
transform: translate(-50%, -50%) !important;
background: rgba(0,0,0,0.7) !important;
}
`}</style>
<div className="e-card-title custom-position">Centered Title</div>Advanced Customization
Custom Card Styling
const cardStyle = {
borderRadius: '12px',
boxShadow: '0 4px 12px rgba(0,0,0,0.1)',
overflow: 'hidden',
transition: 'transform 0.3s ease, box-shadow 0.3s ease'
};
const hoverStyle = {
transform: 'translateY(-4px)',
boxShadow: '0 8px 20px rgba(0,0,0,0.15)'
};
export default function CustomStyledCard() {
const [isHovered, setIsHovered] = React.useState(false);
return (
<div className="e-card"
onMouseEnter={() => setIsHovered(true)}
onMouseLeave={() => setIsHovered(false)}
style={{
...cardStyle,
...(isHovered ? hoverStyle : {})
}}>
<div className="e-card-image"
style={{
backgroundImage: 'url(./image.jpg)',
height: '200px'
}} />
<div className="e-card-content">
<h3>Elevated Card</h3>
<p>Hover to see the elevation effect</p>
</div>
</div>
);
}Card Grid Layout
export default function CardGrid() {
const cards = [
{ id: 1, title: 'Card 1', image: './image1.jpg' },
{ id: 2, title: 'Card 2', image: './image2.jpg' },
{ id: 3, title: 'Card 3', image: './image3.jpg' },
{ id: 4, title: 'Card 4', image: './image4.jpg' }
];
return (
<div style={{
display: 'grid',
gridTemplateColumns: 'repeat(auto-fill, minmax(250px, 1fr))',
gap: '20px',
padding: '20px'
}}>
{cards.map(card => (
<div key={card.id} className="e-card">
<div className="e-card-image"
style={{
backgroundImage: `url(${card.image})`,
height: '200px'
}}>
<div className="e-card-title">{card.title}</div>
</div>
<div className="e-card-content">
<p>Card description</p>
</div>
</div>
))}
</div>
);
}Responsive Patterns
Mobile-First Responsive Card
export default function ResponsiveCard() {
const [isMobile, setIsMobile] = React.useState(window.innerWidth < 768);
React.useEffect(() => {
const handleResize = () => setIsMobile(window.innerWidth < 768);
window.addEventListener('resize', handleResize);
return () => window.removeEventListener('resize', handleResize);
}, []);
return (
<div className={`e-card ${isMobile ? '' : 'e-card-horizontal'}`}
style={{ maxWidth: isMobile ? '100%' : '500px' }}>
<img src="./product.jpg" alt="Product"
style={{
width: isMobile ? '100%' : '150px',
height: isMobile ? '200px' : '150px',
objectFit: 'cover'
}} />
<div className={isMobile ? '' : 'e-card-stacked'}>
<div className="e-card-header">
<div className="e-card-header-caption">
<div className="e-card-header-title">Product Title</div>
</div>
</div>
<div className="e-card-content">Product description</div>
</div>
</div>
);
}CSS Media Query Approach
const styles = `
@media (max-width: 768px) {
.e-card.responsive-card {
flex-direction: column !important;
}
.e-card.responsive-card img {
width: 100% !important;
}
}
@media (min-width: 768px) {
.e-card.responsive-card {
flex-direction: row !important;
}
}
`;
export default function ResponsiveMediaCard() {
return (
<>
<style>{styles}</style>
<div className="e-card responsive-card e-card-horizontal">
<img src="./image.jpg" alt="Sample" style={{ height: '150px' }} />
<div className="e-card-stacked">
<div className="e-card-content">Content here</div>
</div>
</div>
</>
);
}Position Classes Reference
| Class | Position |
|---|---|
e-card-bottom-left | Bottom-left corner (default) |
e-card-bottom-right | Bottom-right corner |
e-card-top-left | Top-left corner |
e-card-top-right | Top-right corner |
Layout Classes Reference
| Class | Purpose |
|---|---|
e-card-horizontal | Horizontal layout |
e-card-stacked | Vertical stack within horizontal |
Tips & Best Practices
1. Container width: Set explicit width for horizontal cards to control proportions
2. Image dimensions: Use consistent image sizes for aligned grids
3. Flex layout: Use flexbox for responsive horizontal layouts
4. Mobile consideration: Test horizontal layouts on mobile—may need to stack vertically
5. Spacing: Use padding and margins for consistent internal spacing
Next: Learn about embedding components to integrate other Syncfusion components within cards.