Download this free Inline Kinetic FAQ code. A modern dark-mode layout where answers smoothly replace questions on hover. Unique, lightweight, and fast.
Table of Contents
Most FAQ sections on the web look the same: you click a box, and it expands down. It works, but it’s boring.
If you want a website that feels "high-end" and unique, you need to break the pattern. Today, I am sharing a free code snippet for an Inline Kinetic Reveal FAQ.
Instead of expanding the page height, this design uses a smart "swap" animation. When a user hovers over a row, the question slides away, and the answer slides in to replace it—all within the same line. It creates a sleek, futuristic system inquiry vibe that looks great on portfolios and agency sites.
Prerequisites
To use this code, you only need:
- Basic HTML/CSS knowledge.
- No Frameworks: We are not using React, jQuery, or Bootstrap. This is pure code.
- Google Fonts: We use the 'Inter' font for a clean, modern look.
Source Code
Step 1 (HTML Code):
The HTML here is very clean because we will generate the actual questions using JavaScript later. This keeps your HTML file short and easy to manage.
We just need a main container and a wrapper for the list (id="faq-list").
Step 2 (CSS Code):
This is where the unique logic lives.
The Secret Sauce: We use CSS Grid to stack the Question and the Answer on top of each other in the same cell (grid-template-areas: 'stack').
- Default State: The Question is visible; the Answer is hidden and pushed to the right.
- Hover State: The Question fades out to the left; the Answer slides in from the right.
Create a file named styles.css and paste this code:
/* --- VARIABLES & RESET --- */
:root {
--bg-primary: #050505;
--bg-hover: #121212;
--text-main: #ffffff;
--text-muted: #9ca3af;
--accent: #ef4444;
--border-color: #262626;
--font-main: 'Inter', sans-serif;
--max-width: 72rem;
}
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
body {
font-family: var(--font-main);
background-color: var(--bg-primary);
color: var(--text-main);
min-height: 100vh;
display: flex;
flex-direction: column;
justify-content: center;
overflow-x: hidden;
padding: 1rem;
}
@media (min-width: 640px) {
body {
padding: 3rem;
}
}
/* --- LAYOUT UTILITIES --- */
.container {
width: 100%;
max-width: var(--max-width);
margin: 0 auto;
}
.header {
margin-bottom: 4rem;
padding-left: 1rem;
padding-right: 1rem;
}
.sub-heading {
color: var(--accent);
font-weight: 700;
letter-spacing: 0.1em;
font-size: 0.75rem;
text-transform: uppercase;
margin-bottom: 0.75rem;
display: block;
}
.main-heading {
font-size: 2.25rem;
font-weight: 700;
line-height: 1.1;
letter-spacing: -0.025em;
color: var(--text-main);
}
@media (min-width: 768px) {
.sub-heading {
font-size: 0.875rem;
}
.main-heading {
font-size: 3.75rem;
}
}
/* --- FAQ ROW STYLING --- */
.faq-list {
width: 100%;
}
.faq-row {
border-top: 1px solid var(--border-color);
transition: background-color 0.3s ease;
position: relative;
min-height: 100px;
cursor: pointer;
-webkit-tap-highlight-color: transparent;
width: 100%;
}
.faq-row:last-child {
border-bottom: 1px solid var(--border-color);
}
.faq-row:hover {
background-color: var(--bg-hover);
}
/* Row Inner Layout */
.faq-row-inner {
display: flex;
align-items: center;
justify-content: space-between;
padding: 2rem 1rem;
width: 100%;
height: 100%;
}
@media (min-width: 768px) {
.faq-row-inner {
padding-left: 2rem;
padding-right: 2rem;
}
}
/* Number Column */
.row-number {
flex-shrink: 0;
padding-right: 1.5rem;
align-self: flex-start;
margin-top: 0.25rem;
}
.number-text {
color: var(--accent);
font-size: 1.125rem;
font-family: monospace;
font-weight: 500;
}
@media (min-width: 768px) {
.row-number {
padding-right: 2.5rem;
align-self: center;
margin-top: 0;
}
}
/* --- TEXT STACKING --- */
.text-stack {
display: grid;
grid-template-areas: 'stack';
align-items: center;
flex-grow: 1;
position: relative;
min-height: 3rem;
}
.question-text,
.answer-text {
grid-area: stack;
transition: all 0.5s cubic-bezier(0.16, 1, 0.3, 1);
}
/* Question State */
.question-text {
font-size: 1.25rem;
font-weight: 600;
line-height: 1.25;
color: var(--text-main);
opacity: 1;
transform: translateX(0);
transform-origin: left center;
z-index: 10;
width: 100%;
margin: 0;
}
@media (min-width: 768px) {
.question-text {
font-size: 1.875rem;
}
}
/* Global Hover: Dim Question */
.faq-row:hover .question-text {
opacity: 0.1;
transform: translateX(-20px);
filter: blur(2px);
}
@media (max-width: 767px) {
.faq-row:hover .question-text {
transform: translateX(-10px);
}
}
/* Answer State */
.answer-text {
font-size: 1rem;
font-weight: 500;
line-height: 1.625;
color: #d1d5db;
opacity: 0;
transform: translateX(30px);
z-index: 20;
pointer-events: none;
/* Alignment */
text-align: right;
display: flex;
justify-content: flex-end;
align-items: center;
}
@media (min-width: 768px) {
.answer-text {
font-size: 1.125rem;
max-width: 70%;
justify-self: end;
}
}
/* Mobile Adjustments for Answer */
@media (max-width: 767px) {
.answer-text {
width: 100%;
font-size: 0.95rem;
text-align: left;
justify-content: flex-start;
}
}
/* Global Hover: Show Answer */
.faq-row:hover .answer-text {
opacity: 1;
transform: translateX(0);
}
/* --- ICON ANIMATION --- */
.icon-column {
position: relative;
width: 1.5rem;
height: 1.5rem;
flex-shrink: 0;
margin-left: 1.5rem;
align-self: flex-start;
margin-top: 0.25rem;
}
@media (min-width: 768px) {
.icon-column {
width: 2rem;
height: 2rem;
align-self: center;
margin-top: 0;
}
}
.icon-wrapper {
width: 100%;
height: 100%;
position: relative;
transition: transform 0.5s cubic-bezier(0.16, 1, 0.3, 1);
}
.icon-svg {
width: 100%;
height: 100%;
position: absolute;
top: 0;
left: 0;
stroke: currentColor;
stroke-width: 2;
fill: none;
transition: opacity 0.4s ease, transform 0.4s ease;
}
.icon-close {
opacity: 0;
transform: rotate(-90deg);
}
/* Hover States for Icons */
.faq-row:hover .icon-wrapper {
transform: rotate(90deg);
}
.faq-row:hover .icon-plus {
opacity: 0;
}
.faq-row:hover .icon-close {
opacity: 1;
transform: rotate(0);
} Step 3 (JavaScript Code):
Using JavaScript here allows us to easily add or remove questions without copying and pasting HTML blocks. We store the questions in a simple array called faqData.
Create a file named script.js:
const faqData = [
{
id: 1,
question: 'What projects are available on CodeWithFaraz?',
answer:
'We offer a diverse range of HTML, CSS, and JavaScript projects, responsive website templates, and creative UI components.',
},
{
id: 2,
question: 'Are the website templates free to use?',
answer:
'Yes, we provide a vast collection of free open-source templates, along with premium, high-quality options.',
},
{
id: 3,
question: 'Do you sell low-rate website templates?',
answer:
'Absolutely. Our premium shop features professional website templates at budget-friendly rates suitable for any project.',
},
{
id: 4,
question: 'Can I use the components for commercial work?',
answer:
'Yes! You are free to use our code snippets and templates for both personal and commercial projects.',
},
{
id: 5,
question: 'How often is new content added?',
answer:
'We regularly update the platform with fresh source code, new design trends, and optimized web components.',
},
];
const listContainer = document.getElementById('faq-list');
listContainer.innerHTML = faqData
.map((item, index) => {
const num = (index + 1).toString().padStart(2, '0');
return `
<div class="faq-row group">
<div class="faq-row-inner">
<!-- Left Number -->
<div class="row-number">
<span class="number-text">${num}</span>
</div>
<!-- Center Stack (Question & Answer Overlay) -->
<div class="text-stack">
<!-- Question -->
<h2 class="question-text">
${item.question}
</h2>
<!-- Answer -->
<div class="answer-text">
${item.answer}
</div>
</div>
<!-- Right Icon -->
<div class="icon-column">
<div class="icon-wrapper">
<svg class="icon-svg icon-plus" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" d="M12 6v6m0 0v6m0-6h6m-6 0H6"></path>
</svg>
<svg class="icon-svg icon-close" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" d="M6 18L18 6M6 6l12 12"></path>
</svg>
</div>
</div>
</div>
</div>
`;
})
.join('');Final Output:
Conclusion:
This Inline Kinetic Reveal FAQ is perfect for developers who want to avoid the "cookie-cutter" look of standard websites. By using this snippet, you create an interactive experience that feels responsive and sharp.
The dark mode aesthetic combined with the smooth text swap makes your content easy to read while keeping the design minimal. Go ahead and copy this into your next project!
That’s a wrap!
I hope you enjoyed this post. Now, with these examples, you can create your own amazing page.
Did you like it? Let me know in the comments below 🔥 and you can support me by buying me a coffee
And don’t forget to sign up to our email newsletter so you can get useful content like this sent right to your inbox!
Thanks!
Faraz 😊


