FAQ rows that peek open on hover to show the first line of the answer, with the chevron nudging down. The row animates grid-template-rows from 0fr to 1fr, so the height is never hard-coded.
Also known as: accordion hover css, faq hover effect, collapsible peek on hover.
Monthly or yearly, switch any time.
Yes, upgrades apply right away.
Within 30 days, no questions asked.
<div class="hfx-accordion-peek">
<div class="hfx-accordion-peek-item">
<button>How does billing work? <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="m6 9 6 6 6-6"/></svg></button>
<p>Monthly or yearly, switch any time.</p>
</div>
<div class="hfx-accordion-peek-item">
<button>Can I change plans later? <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="m6 9 6 6 6-6"/></svg></button>
<p>Yes, upgrades apply right away.</p>
</div>
<div class="hfx-accordion-peek-item">
<button>Do you offer refunds? <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="m6 9 6 6 6-6"/></svg></button>
<p>Within 30 days, no questions asked.</p>
</div>
</div>.hfx-accordion-peek {
--c: var(--hfx-color, #3b82f6);
font-size: var(--hfx-size, 16px);
width: 18em;
border-top: 1px solid color-mix(in srgb, var(--c) 25%, transparent);
font-family: system-ui, sans-serif;
}
.hfx-accordion-peek-item {
display: grid;
grid-template-rows: auto 0fr;
padding-bottom: 0;
border-bottom: 1px solid color-mix(in srgb, var(--c) 25%, transparent);
transition: grid-template-rows 0.35s cubic-bezier(0.3, 0.7, 0.4, 1), padding 0.35s cubic-bezier(0.3, 0.7, 0.4, 1), background-color 0.25s ease;
}
.hfx-accordion-peek button {
display: flex;
align-items: center;
justify-content: space-between;
gap: 1em;
width: 100%;
padding: 0.6em 0.6em;
border: 0;
background: none;
color: inherit;
font: inherit;
font-weight: 600;
text-align: left;
cursor: pointer;
transition: color 0.2s ease;
}
.hfx-accordion-peek button svg {
flex: none;
width: 1.1em;
height: 1.1em;
color: var(--c);
transition: transform 0.35s cubic-bezier(0.34, 1.56, 0.64, 1);
}
.hfx-accordion-peek p {
min-height: 0;
margin: 0;
padding: 0 0.7em;
overflow: hidden;
color: color-mix(in srgb, currentColor 65%, transparent);
font-size: 0.85em;
line-height: 1.4;
opacity: 0;
transform: translateY(-0.4em);
transition: opacity 0.3s ease, transform 0.35s cubic-bezier(0.3, 0.7, 0.4, 1);
}
.hfx-accordion-peek-item:is(:hover, :focus-within) {
grid-template-rows: auto 1fr;
padding-bottom: 0.5em;
background: color-mix(in srgb, var(--c) 6%, transparent);
}
.hfx-accordion-peek-item:is(:hover, :focus-within) button { color: var(--c); }
.hfx-accordion-peek-item:is(:hover, :focus-within) button svg { transform: translateY(0.2em); }
.hfx-accordion-peek-item:is(:hover, :focus-within) p {
opacity: 1;
transform: none;
}
@media (prefers-reduced-motion: reduce) {
.hfx-accordion-peek, .hfx-accordion-peek *, .hfx-accordion-peek::before, .hfx-accordion-peek::after, .hfx-accordion-peek *::before, .hfx-accordion-peek *::after {
animation-duration: 0.01ms !important;
animation-iteration-count: 1 !important;
transition-duration: 0.01ms !important;
}
}--hfx-color on the element or a parent.
Currently previewing #3b82f6.--hfx-size. Every other dimension is in
em, so the whole thing scales together. Currently previewing 16px.transition or animation
shorthand. Staggered delays are relative, so they keep their rhythm.