ElementorProのコールトゥーアクションウィジェットは非常に便利ですが、「投稿のカテゴリーをアイコンで直感的に見せたい」「複数のカテゴリーがある場合に並べて表示したい」といった要望には標準機能だけでは手が届きません。
今回は、JavaScriptとCSSのみで、背景画像の上にカラフルなカテゴリーアイコン(Font Awesome)を表示し、さらにタクソノミーフィルターともデザインを完全に連動させるカスタマイズをご紹介します。
Elementorのコールトゥアクション(CTA)ウィジェットをループ表示(Loop Grid等)させ、さらにタクソノミーフィルターを使用してカテゴリーごとに表示を切り替える実装を想定しています。
Elementor標準のフィルター機能を使う際、通常はAJAX(非同期通信)でコンテンツが切り替わるため、動的に追加したアイコンやスタイルが消えてしまうという課題があります。この記事では、フィルターで表示を切り替えてもアイコンが維持され、さらにツールチップや色分けまで連動させる高度なカスタマイズ方法を解説します。
複数カテゴリー対応: 1つの投稿に複数のカテゴリーがあっても自動で横に並びます。
Font Awesome採用: 小さなサイズ(30px)でも潰れず、視認性が抜群です。
動的ツールチップ: ホバー時にカテゴリー名をふわっと表示。色もカテゴリーに連動します。
フィルター連動: タクソノミーフィルターのボタンにも同じアイコンと色を適用。
AJAX対応: フィルター切り替え時もアイコンが消えない設計(MutationObserver使用)。
まずは見た目を整えるCSSです。Elementorの [サイト設定] > [カスタムCSS] または子テーマの style.css に追加してください。
/* --- CTAカード内のアイコンコンテナ --- */
.cta-multi-icon-container {
position: absolute;
top: 10px;
right: 10px;
display: flex;
gap: 5px;
z-index: 99;
pointer-events: auto;
}
/* アイコン丸枠(30px) */
.cta-individual-icon {
position: relative;
width: 30px;
height: 30px;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
box-shadow: 0 2px 4px rgba(0,0,0,0.15);
cursor: help;
}
.cta-individual-icon i {
color: #ffffff !important;
font-size: 14px;
line-height: 1;
}
/* --- ツールチップ(吹き出し) --- */
.cta-individual-icon::after {
content: attr(data-tooltip);
position: absolute;
right: 130%;
top: 50%;
transform: translateY(-50%);
color: #ffffff;
padding: 4px 8px;
border-radius: 4px;
font-size: 11px;
white-space: nowrap;
opacity: 0;
visibility: hidden;
transition: all 0.2s ease-in-out;
pointer-events: none;
box-shadow: 0 2px 5px rgba(0,0,0,0.2);
}
.cta-individual-icon:hover::after {
opacity: 1;
visibility: visible;
right: 140%;
}
/* --- タクソノミーフィルターボタン --- */
.e-filter-item {
border: none !important;
color: #ffffff !important;
margin-bottom: 5px !important;
}
/* --- カテゴリー毎の色分け設定 --- */
/* 買う (kau) */
.cta-individual-icon.kau, .cta-individual-icon.kau::after, .e-filter-item[data-filter="kau"] { background-color: #e91e63 !important; }
/* 食べる (inshoku) */
.cta-individual-icon.inshoku, .cta-individual-icon.inshoku::after, .e-filter-item[data-filter="inshoku"] { background-color: #ff9800 !important; }
/* 憩う・泊まる (ikou) */
.cta-individual-icon.ikou, .cta-individual-icon.ikou::after, .e-filter-item[data-filter="ikou"] { background-color: #4caf50 !important; }
/* 暮らし・サービス (kurashi) */
.cta-individual-icon.kurashi, .cta-individual-icon.kurashi::after, .e-filter-item[data-filter="kurashi"] { background-color: #2196f3 !important; }
/* すべて */
.e-filter-item[data-filter="__all"] { background-color: #777777 !important; }アイコンを生成し、フィルターの動作を監視するスクリプトです。Elementorの [カスタムコード] またはHTMLウィジェットを使用して設置してください。
<script>
(function() {
const iconConfig = {
'kau': { label: '買う', fa: 'fas fa-shopping-bag' },
'inshoku': { label: '食べる', fa: 'fas fa-utensils' },
'ikou': { label: '憩う・泊まる', fa: 'fas fa-bed' },
'kurashi': { label: '暮らし・サービス', fa: 'fas fa-home' }
};
const renderAllIcons = () => {
// 1. CTAカードへのアイコン挿入
const widgets = document.querySelectorAll('.elementor-widget-call-to-action');
widgets.forEach(widget => {
if (widget.querySelector('.cta-multi-icon-container')) return;
const ctaElement = widget.querySelector('.elementor-cta');
if (!ctaElement) return;
const container = document.createElement('div');
container.className = 'cta-multi-icon-container';
const itemElement = widget.closest('.e-loop-item') || widget;
const classes = Array.from(itemElement.classList);
Object.keys(iconConfig).forEach(key => {
if (classes.includes(key) || classes.includes('category-' + key)) {
const iconItem = document.createElement('div');
iconItem.className = 'cta-individual-icon ' + key;
iconItem.setAttribute('data-tooltip', iconConfig[key].label);
const i = document.createElement('i');
i.className = iconConfig[key].fa;
iconItem.appendChild(i);
container.appendChild(iconItem);
}
});
if (container.hasChildNodes()) ctaElement.appendChild(container);
});
// 2. フィルターボタンへのアイコン挿入
const filterButtons = document.querySelectorAll('.e-filter-item');
filterButtons.forEach(button => {
if (button.querySelector('i')) return;
const filterValue = button.getAttribute('data-filter');
if (iconConfig[filterValue]) {
const i = document.createElement('i');
i.className = iconConfig[filterValue].fa;
i.style.marginRight = '8px';
button.prepend(i);
}
});
};
// 初回実行
window.addEventListener('load', renderAllIcons);
// タクソノミーフィルター等のAJAXによるDOM変更を監視
const observer = new MutationObserver(() => renderAllIcons());
observer.observe(document.body, { childList: true, subtree: true });
})();
</script>ループ表示とタクソノミーフィルターを組み合わせた動的なサイト制作では、AJAXによる表示崩れを防ぐための対策が必須です。今回の実装方法を使えば、Elementorの利便性を活かしつつ、細部までデザインされた高度なカテゴリー表示が可能になります。
観光案内や店舗一覧など、カテゴリーが重要な役割を果たすサイト制作にぜひ役立ててください。