This setup ensures that clicking a link only affects its specific container without reloading the page.
1. Elementor Structure
For every 2-column section you create, follow this naming convention in the Advanced > CSS Classes field:
Main Container:
expandable-container.Note: To keep the image filling the left column, set the image as the Column Background (Style > Background) with Size set to Cover.
The “Extra” Text Widget:
hidden-content.The Link/Button:
read-more-link.
2. CSS Styling
Add this to Appearance > Customize > Additional CSS. It handles the visibility and the smooth expansion effect.
/* Hide the extra text by default */
.expandable-container .hidden-content {
display: none;
opacity: 0;
transition: opacity 0.4s ease;
}
/* Show content when the container has the active class */
.expandable-container.is-expanded .hidden-content {
display: block;
opacity: 1;
}
/* Ensure a smooth growth of the container */
.expandable-container {
transition: all 0.3s ease-in-out;
}
3. JavaScript for functions.php
Add this to your child theme’s functions.php file. This uses event delegation, meaning one script handles every “Read More” link on the entire page independently.
add_action('wp_footer', 'register_read_more_script');
function register_read_more_script() {
?>
<script>
document.addEventListener('click', function(e) {
// Check if the clicked element has our specific class
if (e.target.classList.contains('read-more-link')) {
e.preventDefault();
// Find the closest container relative to the clicked link
const container = e.target.closest('.expandable-container');
if (container) {
// Toggle the expanded class ONLY on this container
container.classList.toggle('is-expanded');
// Update the text of the link
if (container.classList.contains('is-expanded')) {
e.target.textContent = 'Read Less';
} else {
e.target.textContent = 'Read More';
}
}
}
});
</script>
<?php
}
Why this works
Individuality: Using
e.target.closest()ensures that clicking “Read More” on Section A doesn’t accidentally open Section B.Responsive: Because your left-hand image is set to “Cover” on the column background, it will automatically stretch to match the new height of the text column as it expands.
Performance: This script waits for a click rather than running constantly, keeping your site fast.