Modules
Comparison
Comparison table modules including sticky headers and ways-to-pay layouts.
Comparison
Description
Comparison modules show product or payment options side by side in a table layout. Some variants use a sticky header on desktop and expandable columns on mobile.
How to edit
- Go to Elementor → Editor → Templates.
- Search for
Comparison(or a word from the specific template name below). - Open the template and edit the column headings and cell content directly.
- Save, then check a page that uses the template.
Edit the copy inside the existing columns rather than adding or removing structure, so the table stays aligned and the sticky and expand behaviour keeps working.
Variants
| Template | What it is |
|---|---|
CK – Comparison – Homepage | The homepage comparison module. |
CK – Comparison – Ways to Pay | Ways to pay, with sticky headings on desktop (uses ck-ways-to-pay) |
CK – Comparison – Whats the Difference | Side-by-side product comparison |
How it behaves
- Any column with the
ck-highlightedclass is expanded by default. - On tablet and mobile (under 1024px), tapping a column heading expands or collapses that column.
- On desktop, a copy of the column headings stays fixed to the top of the screen while you scroll through the Ways to Pay table, so you can always see which column you are reading.
Classes
Primary classes used by the comparison component:
| Class | What it's for |
|---|---|
ck-comparison | Main wrapper |
ck-ways-to-pay | Ways-to-pay variant, used alongside ck-comparison |
ck-comparison__column | A single column |
ck-comparison__column-header | Column heading |
ck-highlighted | Marks a column that starts expanded |
ck-active | Applied to an expanded column |
ck-sticky-active | Applied while the sticky heading is showing |
Styling is done through a combination of the built-in page builder options as well as custom CSS where needed.
Script
This script is added using the HTML editor template. It handles the expandable columns on mobile and the sticky headings on desktop.
<script>
(() => {
document.addEventListener("DOMContentLoaded", () => {
const highlightedColumns = document.querySelectorAll(
".ck-comparison__column.ck-highlighted",
);
highlightedColumns.forEach((column) => {
column.classList.add("ck-active");
});
const columnHeaders = document.querySelectorAll(
".ck-comparison__column-header",
);
columnHeaders.forEach((header) => {
header.addEventListener("click", () => {
if (window.innerWidth > 1023) return;
const column = header.closest(".ck-comparison__column");
if (column) {
column.classList.toggle("ck-active");
}
});
const stickyHeader = header.cloneNode(true);
stickyHeader.classList.add(
"ck-comparison__column-header--sticky",
);
header.after(stickyHeader);
});
const comparison = document.querySelector(
".ck-comparison.ck-ways-to-pay",
);
if (!comparison) return;
// Matches .ck-comparison__column-header--sticky { top: 239px }
const STICKY_HEADER_TOP = 239;
const STICKY_BOTTOM_OFFSET = 400;
let ticking = false;
let headerDocTop = 0;
let comparisonDocBottom = 0;
const originalHeader = comparison.querySelector(
".ck-comparison__column-header:not(.ck-comparison__column-header--sticky)",
);
if (!originalHeader) return;
const getDocTop = (el) =>
el.getBoundingClientRect().top + window.scrollY;
// Measure document positions with sticky off so thresholds stay stable.
const measure = () => {
const wasSticky =
comparison.classList.contains("ck-sticky-active");
if (wasSticky) comparison.classList.remove("ck-sticky-active");
headerDocTop = getDocTop(originalHeader);
comparisonDocBottom =
getDocTop(comparison) + comparison.offsetHeight;
if (wasSticky) comparison.classList.add("ck-sticky-active");
};
const updateStickyState = () => {
ticking = false;
if (window.innerWidth < 1024) {
comparison.classList.remove("ck-sticky-active");
return;
}
const y = window.scrollY;
const shouldStick =
y >= headerDocTop - STICKY_HEADER_TOP &&
y < comparisonDocBottom - STICKY_BOTTOM_OFFSET;
comparison.classList.toggle("ck-sticky-active", shouldStick);
};
const onScroll = () => {
if (!ticking) {
ticking = true;
requestAnimationFrame(updateStickyState);
}
};
const onResize = () => {
measure();
updateStickyState();
};
window.addEventListener("scroll", onScroll, { passive: true });
window.addEventListener("resize", onResize);
measure();
updateStickyState();
});
})();
</script>