Shopify FAQ Section with Image & Expandable Table – Interactive & Responsive
Add an interactive FAQ section with an expandable table and an image to your Shopify store. Fully responsive and customizable for better user engagement.
Liquid Code
<!--
Custom Shopify FAQ Section with Image & Expandable Table
===================================
Tech Stack:
- HTML, CSS (grid layout & animations)
- JavaScript (FAQ expand/collapse)
- Shopify's Liquid templating language
Features:
- Interactive FAQ section with expandable answers
- Responsive two-column grid layout with a large image
- Clickable table rows with smooth expand/collapse animations
- Customizable colors, padding, and layout
Promotion:
For more prebuilt Shopify templates, visit: https://prebuilttemplates.com/
===================================
-->
<style>
.section-{{ section.id }} {
display: grid;
grid-template-columns: 1fr 2fr;
gap: 20px;
color: #000;
font-size: 21px;
}
.faq-container{
padding-top: {{ section.settings.padding_top }}px;
padding-bottom: {{ section.settings.padding_bottom }}px;
}
.section-{{ section.id }} .image-block img {
width: 100%;
height: auto;
object-fit: cover;
}
.section-{{ section.id }} .text-title {
font-size: 24px;
font-weight: bold;
margin-top: 20px;
text-align: center;
}
.section-{{ section.id }} .table-title-cont {
display: flex;
flex-direction: column;
padding-left: 180px;
justify-content: space-between;
}
.table-row {
text-transform: uppercase;
color: #000;
font-family: Vercetti;
font-size: 18px;
cursor: pointer;
position: relative;
transition: background-color 0.3s ease;
}
.section-{{ section.id }} .table-header {
display: grid;
grid-template-columns: 2fr 1fr 1fr;
font-weight: bold;
border-bottom: 1px solid #000;
padding-bottom: 10px;
margin-bottom: 10px;
}
.section-{{ section.id }} .table-row {
display: grid;
grid-template-columns: 2fr 1fr 1fr;
padding: 5px 0;
border-bottom: 1px solid #000;
}
.section-{{ section.id }} .table-row:last-child {
border-bottom: none;
}
.section-{{ section.id }} .faq-answer {
display: none;
grid-column: span 3;
font-size: 16px;
color: #555;
padding: 10px 0;
overflow: hidden;
height: 0;
transition: height 0.3s ease, padding 0.3s ease;
}
.section-{{ section.id }} .faq-answer.open {
display: block;
height: auto;
padding: 10px 0;
}
.section-title {
border-bottom: 1px solid;
margin-bottom: 20px;
}
.table-title-cont .text-title {
font-size: 11rem;
color: #000;
text-transform: uppercase;
letter-spacing: 0;
text-align: left;
line-height: 1;
font-style: italic;
max-width: 869px;
}
.text-title-wrap {
display: flex;
justify-content: end;
}
/* Responsive Design */
@media screen and (max-width: 768px) {
.section-{{ section.id }} {
grid-template-columns: 1fr;
}
}
</style>
<div class="faq-container right-left-p">
<div class="section-title"><h1>FAQ.</h1></div>
<div class="section-{{ section.id }} ">
<!-- Left Column: Image -->
<div class="image-block">
<img src="{{ section.settings.image | img_url: 'master' }}" alt="Section Image">
</div>
<!-- Right Column: Title and Dynamic Table -->
<div class="table-title-cont">
<div class="table-block">
<!-- Table -->
<div class="table-header">
<div>(Project)</div>
<div>(Place)</div>
<div>(Year)</div>
</div>
{% for block in section.blocks %}
<div class="table-row" onclick="toggleFaq(this)">
<div>{{ block.settings.project }}</div>
<div>{{ block.settings.place }}</div>
<div>{{ block.settings.year }}</div>
</div>
{% if block.settings.faq_answer != blank %}
<div class="faq-answer">
{{ block.settings.faq_answer }}
</div>
{% endif %}
{% endfor %}
</div>
<!-- Section Title -->
<div class="text-title-wrap">
<div class="text-title">{{ section.settings.title }}</div>
</div>
</div>
</div>
</div>
<script>
function toggleFaq(row) {
const allAnswers = document.querySelectorAll('.faq-answer');
const nextElement = row.nextElementSibling;
// Close all open FAQs
allAnswers.forEach((answer) => {
if (answer !== nextElement) {
answer.style.padding = '0';
setTimeout(() => {
answer.classList.remove('open');
}, 300);
}
});
// Toggle the clicked FAQ
if (nextElement && nextElement.classList.contains('faq-answer')) {
if (!nextElement.classList.contains('open')) {
nextElement.style.padding = '10px 0';
nextElement.classList.add('open');
} else {
nextElement.style.padding = '0';
setTimeout(() => {
nextElement.classList.remove('open');
}, 300);
}
}
}
</script>
{% schema %}
{
"name": "Image and FAQ ",
"settings": [
{
"type": "image_picker",
"id": "image",
"label": "Left Image"
},
{
"type": "text",
"id": "title",
"label": "Section Title",
"default": "What People Say About Us?"
},
{
"type": "range",
"id": "padding_top",
"label": "Padding Top",
"min": 0,
"max": 100,
"step": 5,
"default": 20
},
{
"type": "range",
"id": "padding_bottom",
"label": "Padding Bottom",
"min": 0,
"max": 100,
"step": 5,
"default": 20
}
],
"blocks": [
{
"type": "table_row",
"name": "Table Row",
"settings": [
{
"type": "text",
"id": "project",
"label": "Project",
"default": "TD 213 - Modern Harmony"
},
{
"type": "text",
"id": "place",
"label": "Place",
"default": "Kyiv"
},
{
"type": "text",
"id": "year",
"label": "Year",
"default": "2024"
},
{
"type": "richtext",
"id": "faq_answer",
"label": "FAQ Answer"
}
]
}
],
"presets": [
{
"name": "Image and FAQ Table Section",
"blocks": [
{
"type": "table_row"
},
{
"type": "table_row"
},
{
"type": "table_row"
}
]
}
]
}
{% endschema %}
