Three images are hidden inside every card. On desktop, hovering triggers a CSS fan animation. On mobile, tapping reveals the images stacked below the text. Everything is driven by two HTML widgets and a set of CSS classes you assign in Elementor's Advanced tab.
.zip archive containing the layout JSON.
.json files directly to the Media Library. To work around this:
- Download the
.zipfile above and extract the.jsonfile on your computer. - In WordPress, navigate to Templates → Saved Templates.
- Click Import Templates at the top, select your extracted
.jsonfile, and click Import Now. - Once imported, simply load the template inside your Elementor canvas by opening the template library folder icon and choosing your saved template!
Architecture tree
This is the Elementor widget hierarchy. Place the Styles Widget first and the Script Widget last within your parent column container.
Fan Section (Elementor Section) └── Parent (single Column inside Section) │ ├── Styles Widget (HTML Widget) ← FIRST element inside Parent │ ├── Card 1 (Inner Section · Advanced CSS Classes: fan-card) │ ├── Text Column (e.g. 55% width) │ │ ├── Tag widget (Text Widget · Advanced CSS Classes: fan-tag) │ │ └── Title widget (Heading Widget · Advanced CSS Classes: fan-title) │ └── Images Column (e.g. 45% width · Advanced CSS Classes on the column: fan-imgs-col) │ ├── Left Image (Image Widget · Advanced CSS Classes: fan-img) │ ├── Centre Image (Image Widget · Advanced CSS Classes: fan-img) │ └── Right Image (Image Widget · Advanced CSS Classes: fan-img) │ ├── Card 2 (Inner Section · Advanced CSS Classes: fan-card) │ ├── Text Column │ │ ├── Tag widget (Advanced CSS Classes: fan-tag) │ │ └── Title widget (Advanced CSS Classes: fan-title) │ └── Images Column (Advanced CSS Classes on the column: fan-imgs-col) │ ├── Left Image (Advanced CSS Classes: fan-img) │ ├── Centre Image (Advanced CSS Classes: fan-img) │ └── Right Image (Advanced CSS Classes: fan-img) │ ├── Card 3 (Inner Section · Advanced CSS Classes: fan-card) │ └── Same structure — all cards use the exact same classes │ └── Script Widget (HTML Widget) ← LAST element inside Parent
CSS class reference
Assign these classes in the Advanced → CSS Classes tab of each Elementor item. Match the targets precisely for the widgets to be identified by the script.
| Element | CSS class | Applied to |
|---|---|---|
| Every card Inner Section | fan-card | Inner Section Settings |
| Images Column (inside card) | fan-imgs-col | Column Settings |
| All three Image widgets | fan-img | Image Widget Settings |
| Tag Text Widget | fan-tag | Text Editor Widget Settings |
| Title Heading Widget | fan-title | Heading Widget Settings |
Step-by-step build guide
Add a new Section to your page containing a single column. All cards and both HTML code widgets must live directly inside this column (the "Parent" column).
Drag an HTML widget to the very top of the Parent column. This will act as the Styles Widget. Leave it empty for now; you will add the CSS code in the next section.
Insert an Inner Section below the Styles Widget and set it to a 2-column layout. Open the Inner Section settings, go to the Advanced tab, and set the CSS Classes field to: fan-card
In the left column of Card 1's Inner Section:
- Add a Text Editor widget.
- In its Advanced tab, set the CSS Class to:
fan-tag
- Add a Heading widget.
- In its Advanced tab, set the CSS Class to:
fan-title
In the right column of Card 1's Inner Section:
- Click the column border to edit the column itself.
- In the Advanced tab, set the CSS Class to:
fan-imgs-col
- Drag three Image widgets into this column. Order is key: the 1st widget acts as the left image, the 2nd as the centre, and the 3rd as the right.
- For all three Image widgets, set the CSS Class in the Advanced tab to:
fan-img
Duplicate Card 1 to create Card 2 and Card 3. The CSS classes are preserved automatically. Simply swap the images and change the text content.
Drag a second HTML widget to the very bottom of the Parent column (below all card sections). This is your Script Widget.
The two code widgets
Paste the corresponding codes into the HTML widgets created in the steps above.
Widget 1 — Styles Widget (paste inside the first HTML widget)
Widget 2 — Script Widget (paste inside the second HTML widget)
Mobile behaviour & touch screens
On touch screens, the gorgeous three-image fan animation is fully preserved. Since hover does not exist on mobile devices, a tap toggle is used instead. Tapping a card dims its background and fans the three images out dynamically, while the text shifts to high-contrast white layered on top for legibility.
Elementor Breakpoint Setup
Switch to the Mobile Breakpoint viewport within the Elementor editor. For each card section:
- Set the Text column width to 100%.
- Set the Images column width to 100% (which remains hidden as the template data source).
The stylesheet automatically applies responsive scaling so the fanned images fit smaller viewports without overflowing, and the script handles the click toggle, closing any other active cards when a new one is tapped.
Troubleshooting
Ensure that the CSS class fan-imgs-col is applied directly to the Column Settings containing the images, and not inside individual image widgets. The Styles Widget must also load at the very top of your parent column container so it applies initial hiding rules before widgets render.
Verify that your Text and Heading widgets have the classes fan-tag and fan-title applied. The stylesheet forces elements with these classes to use `position: relative` and a higher `z-index: 10` so they sit clearly on top of the fanned images.
Check that the Script Widget is placed as the very last element in the Parent column. Open your browser console (F12) to ensure there are no other JavaScript errors on the page blocking execution.
Pre-publish checklist
Confirm these technical steps before publishing the page:
How it works — layers and pseudo-elements
The card is a position: relative stacking context. Everything inside it is layered by z-index. The text sits at z-index: 10, always on top. The images live at z-index: 2. Two CSS pseudo-elements handle the styling decoration:
| Selector | What it does |
|---|---|
| .fan-card::before | Dark dimming overlay at z-index: 1. Invisible at rest (opacity: 0). When JS adds .fan-active to the card, it fades to opacity: 1 — pushing the card background into shadow so the fan images stand out clearly. |
| .fan-card::after | Dot-grid texture at z-index: 0. Visible at rest, giving the dark card surface depth. Fades to opacity: 0 on hover so images appear against a clean background without noise behind them. |
| .fan-float-wrapper::after | Vignette gradient on each individual image. Always visible once images are revealed. This requires a <div> wrapper around each <img> — pseudo-elements cannot attach to <img> tags because images are replaced elements with no children. The Script Widget creates these wrappers automatically. |
All fan images start collapsed and hidden at rest. The centre starts scaled down, and the flanking side images start rotated and tucked behind. When the card container receives .fan-active, CSS transitions translate, scale, and rotate them to their open positions.