MJML component for creating interactive image carousels in email templates with thumbnail navigation and cross-client compatibility
npx @tessl/cli install tessl/npm-mjml-carousel@4.15.00
# MJML Carousel
1
2
MJML Carousel provides interactive image carousel components for email templates. It uses CSS-only interactivity with radio buttons and selectors to create cross-client compatible carousels with thumbnail navigation, hover effects, and click-through functionality.
3
4
## Package Information
5
6
- **Package Name**: mjml-carousel
7
- **Package Type**: npm
8
- **Language**: JavaScript (ES6+ with Babel transpilation)
9
- **Installation**: `npm install mjml-carousel`
10
11
## Core Imports
12
13
```javascript
14
import { Carousel, CarouselImage } from "mjml-carousel";
15
```
16
17
For CommonJS:
18
19
```javascript
20
const { Carousel, CarouselImage } = require("mjml-carousel");
21
```
22
23
## Basic Usage
24
25
```xml
26
<mjml>
27
<mj-body>
28
<mj-section>
29
<mj-column>
30
<mj-carousel>
31
<mj-carousel-image src="https://example.com/image1.jpg" />
32
<mj-carousel-image src="https://example.com/image2.jpg" />
33
<mj-carousel-image src="https://example.com/image3.jpg" />
34
</mj-carousel>
35
</mj-column>
36
</mj-section>
37
</mj-body>
38
</mjml>
39
```
40
41
## Architecture
42
43
The mjml-carousel package is built around the MJML component system:
44
45
- **Component Architecture**: Extends BodyComponent from mjml-core for consistent MJML integration
46
- **CSS-only Interactivity**: Uses radio buttons and CSS selectors for carousel navigation without JavaScript
47
- **Email Client Compatibility**: Includes MSO conditional tags and fallback rendering for maximum compatibility
48
- **Responsive Design**: Automatically adjusts thumbnail sizes and layout based on container width
49
- **Lazy Generation**: Generates styles and markup dynamically based on the number of child images
50
51
## Capabilities
52
53
### Carousel Container Component
54
55
Main carousel container that orchestrates image display, navigation controls, and thumbnail generation.
56
57
```javascript { .api }
58
class MjCarousel extends BodyComponent {
59
static componentName: string; // 'mj-carousel'
60
static allowedAttributes: object;
61
static defaultAttributes: object;
62
63
/**
64
* @param initialDatas - Component initialization data including children and attributes
65
*/
66
constructor(initialDatas?: object): void;
67
68
/**
69
* Generates CSS styles for carousel functionality including radio button selectors
70
* @returns CSS string for component head styles
71
*/
72
componentHeadStyle(): string;
73
74
/**
75
* Returns style configuration object for different carousel elements
76
* @returns Object containing CSS styles organized by element type
77
*/
78
getStyles(): StyleConfig;
79
80
/**
81
* Calculates thumbnail width based on container width and number of images
82
* @returns CSS width value as string
83
*/
84
thumbnailsWidth(): string;
85
86
/**
87
* Extracts attributes from all child carousel images
88
* @returns Array of attribute objects from child components
89
*/
90
imagesAttributes(): object[];
91
92
/**
93
* Generates HTML for radio button inputs used for carousel navigation
94
* @returns HTML string containing all radio inputs
95
*/
96
generateRadios(): string;
97
98
/**
99
* Generates HTML for thumbnail navigation (if thumbnails are visible)
100
* @returns HTML string for thumbnail navigation or empty string
101
*/
102
generateThumbnails(): string;
103
104
/**
105
* Generates navigation control icons (previous/next arrows)
106
* @param direction - Either 'previous' or 'next'
107
* @param icon - URL of the icon image to use
108
* @returns HTML string for navigation controls
109
*/
110
generateControls(direction: string, icon: string): string;
111
112
/**
113
* Generates the main image container with all carousel images
114
* @returns HTML string containing image container and all images
115
*/
116
generateImages(): string;
117
118
/**
119
* Generates the complete carousel table structure
120
* @returns HTML string for the main carousel table
121
*/
122
generateCarousel(): string;
123
124
/**
125
* Generates fallback content for email clients that don't support CSS
126
* @returns HTML string with MSO conditional tags for fallback
127
*/
128
renderFallback(): string;
129
130
/**
131
* Main render method that outputs the complete carousel HTML
132
* @returns Complete HTML string for the carousel component
133
*/
134
render(): string;
135
}
136
```
137
138
**Allowed Attributes:**
139
140
```javascript { .api }
141
interface CarouselAttributes {
142
align?: 'left' | 'center' | 'right'; // Default: 'center'
143
'border-radius'?: string; // CSS unit(px,%), default: '6px'
144
'container-background-color'?: string; // CSS color
145
'icon-width'?: string; // CSS unit(px,%), default: '44px'
146
'left-icon'?: string; // URL, default: 'https://i.imgur.com/xTh3hln.png'
147
padding?: string; // CSS unit(px,%), 1-4 values
148
'padding-top'?: string; // CSS unit(px,%)
149
'padding-bottom'?: string; // CSS unit(px,%)
150
'padding-left'?: string; // CSS unit(px,%)
151
'padding-right'?: string; // CSS unit(px,%)
152
'right-icon'?: string; // URL, default: 'https://i.imgur.com/os7o9kz.png'
153
thumbnails?: 'visible' | 'hidden'; // Default: 'visible'
154
'tb-border'?: string; // CSS border format, default: '2px solid transparent'
155
'tb-border-radius'?: string; // CSS unit(px,%), default: '6px'
156
'tb-hover-border-color'?: string; // CSS color, default: '#fead0d'
157
'tb-selected-border-color'?: string; // CSS color, default: '#ccc'
158
'tb-width'?: string; // CSS unit(px,%), auto-calculated if not specified
159
}
160
```
161
162
**Usage Examples:**
163
164
```xml
165
<!-- Basic carousel -->
166
<mj-carousel>
167
<mj-carousel-image src="image1.jpg" />
168
<mj-carousel-image src="image2.jpg" />
169
</mj-carousel>
170
171
<!-- Customized carousel -->
172
<mj-carousel
173
align="left"
174
thumbnails="hidden"
175
border-radius="10px"
176
tb-hover-border-color="#ff6600">
177
<mj-carousel-image src="image1.jpg" alt="Product 1" />
178
<mj-carousel-image src="image2.jpg" alt="Product 2" />
179
</mj-carousel>
180
```
181
182
### Carousel Image Component
183
184
Individual image component within carousel supporting linking, custom thumbnails, and detailed configuration.
185
186
```javascript { .api }
187
class MjCarouselImage extends BodyComponent {
188
static componentName: string; // 'mj-carousel-image'
189
static endingTag: boolean; // true - can contain HTML content
190
static allowedAttributes: object;
191
static defaultAttributes: object;
192
193
/**
194
* Returns style configuration object for image, thumbnail, and radio elements
195
* @returns Object containing CSS styles for different image states and elements
196
*/
197
getStyles(): ImageStyleConfig;
198
199
/**
200
* Renders the thumbnail version of the image for navigation
201
* @returns HTML string for thumbnail link with image
202
*/
203
renderThumbnail(): string;
204
205
/**
206
* Renders the radio button input for this carousel image
207
* @returns HTML string for radio input element
208
*/
209
renderRadio(): string;
210
211
/**
212
* Main render method that outputs the carousel image HTML
213
* @returns HTML string for the main carousel image with optional link wrapper
214
*/
215
render(): string;
216
}
217
```
218
219
**Allowed Attributes:**
220
221
```javascript { .api }
222
interface CarouselImageAttributes {
223
alt?: string; // Image alt text, default: ''
224
href?: string; // Link URL when image is clicked
225
rel?: string; // Link relationship attribute
226
target?: string; // Link target, default: '_blank'
227
title?: string; // Image title/tooltip
228
src?: string; // Main image source URL
229
'thumbnails-src'?: string; // Separate thumbnail image source
230
'border-radius'?: string; // CSS unit for image border radius
231
'tb-border'?: string; // CSS border for thumbnail
232
'tb-border-radius'?: string; // CSS unit for thumbnail border radius
233
'css-class'?: string; // Additional CSS class names
234
}
235
```
236
237
**Usage Examples:**
238
239
```xml
240
<!-- Basic image -->
241
<mj-carousel-image src="https://example.com/product.jpg" />
242
243
<!-- Image with link and custom thumbnail -->
244
<mj-carousel-image
245
src="https://example.com/product.jpg"
246
thumbnails-src="https://example.com/product-thumb.jpg"
247
href="https://example.com/product-page"
248
alt="Premium Product"
249
title="Click to view product details" />
250
251
<!-- Image with custom styling -->
252
<mj-carousel-image
253
src="https://example.com/image.jpg"
254
border-radius="15px"
255
css-class="featured-image" />
256
```
257
258
### Advanced Configuration
259
260
**Custom Navigation Icons:**
261
262
```xml
263
<mj-carousel
264
left-icon="https://example.com/custom-left.png"
265
right-icon="https://example.com/custom-right.png"
266
icon-width="60px">
267
<mj-carousel-image src="image1.jpg" />
268
<mj-carousel-image src="image2.jpg" />
269
</mj-carousel>
270
```
271
272
**Thumbnail Styling:**
273
274
```xml
275
<mj-carousel
276
tb-width="80px"
277
tb-border="3px solid #ddd"
278
tb-border-radius="8px"
279
tb-hover-border-color="#007bff"
280
tb-selected-border-color="#28a745">
281
<mj-carousel-image src="image1.jpg" />
282
<mj-carousel-image src="image2.jpg" />
283
</mj-carousel>
284
```
285
286
## Types
287
288
```javascript { .api }
289
// Base component types from mjml-core
290
interface BodyComponent {
291
constructor(initialDatas?: object): void;
292
getAttribute(name: string): string;
293
htmlAttributes(attributes: object): string;
294
renderChildren(children: any[], options?: object): string;
295
context: {
296
containerWidth: string;
297
parentWidth: number;
298
};
299
props: {
300
children: any[];
301
index: number;
302
};
303
attributes: object;
304
}
305
306
// CSS Properties type
307
interface CSSProperties {
308
[property: string]: string | number;
309
}
310
311
// Style configuration object for MjCarousel
312
interface StyleConfig {
313
carousel: {
314
div: CSSProperties;
315
table: CSSProperties;
316
};
317
images: {
318
td: CSSProperties;
319
};
320
controls: {
321
div: CSSProperties;
322
img: CSSProperties;
323
td: CSSProperties;
324
};
325
}
326
327
// Style configuration object for MjCarouselImage
328
interface ImageStyleConfig {
329
images: {
330
img: CSSProperties;
331
firstImageDiv: CSSProperties;
332
otherImageDiv: CSSProperties;
333
};
334
radio: {
335
input: CSSProperties;
336
};
337
thumbnails: {
338
a: CSSProperties;
339
img: CSSProperties;
340
};
341
}
342
```
343
344
## Email Client Compatibility
345
346
The carousel component includes extensive compatibility features:
347
348
- **MSO Conditional Tags**: Provides fallback content for Outlook clients
349
- **CSS Selector Limitations**: Uses radio button technique that works across most email clients
350
- **Progressive Enhancement**: Gracefully degrades to show first image in unsupported clients
351
- **Yahoo Mail Support**: Special CSS handling for Yahoo Mail quirks
352
- **Mobile Responsive**: Automatic thumbnail sizing for mobile email clients
353
354
**Fallback Behavior:**
355
- Unsupported clients display the first image only
356
- Navigation controls are hidden in clients without CSS support
357
- Thumbnails are hidden in Outlook Web App
358
- MSO conditional comments provide alternative markup for Outlook desktop clients