CTA block with CQ
Responsive call-to-action block that adapts layout via container queries — no JavaScript needed.
Ready to get started?
Join thousands of developers building better web experiences.
Unlock premium features
Upgrade today and get access to exclusive tools.
Quick implementation
/* HTML:
<div class="cta-wrapper">
<div class="cta-block">
<div class="cta-content">
<h3>Title</h3>
<p>Description</p>
</div>
<div class="cta-actions">
<button class="cta-btn primary">Primary</button>
<button class="cta-btn secondary">Secondary</button>
</div>
</div>
</div>
*/
.cta-wrapper {
container-type: inline-size;
container-name: cta;
}
.cta-block {
display: flex;
flex-direction: column;
gap: 1rem;
padding: 1.5rem;
border-radius: var(--radius);
background: oklch(0.22 0.03 260);
}
.cta-content h3 {
margin: 0;
font-size: 1.25rem;
}
.cta-actions {
display: flex;
gap: 0.75rem;
}
.cta-btn {
flex: 1;
padding: 0.65rem 1rem;
border-radius: var(--radius);
font-weight: 600;
cursor: pointer;
}
.cta-btn--primary {
background: var(--accent);
border: 1px solid var(--accent);
color: white;
}
.cta-btn--secondary {
background: transparent;
border: 1px solid var(--card-border);
color: var(--text);
}
/* Wide layout (container >= 20rem) */
@container cta (min-width: 20rem) {
.cta-block {
flex-direction: row;
align-items: center;
}
.cta-content {
flex: 1;
}
.cta-actions {
flex: 0 0 auto;
min-width: 12rem;
}
}
/* Narrow layout (container < 20rem) */
@container cta (max-width: 19.99rem) {
.cta-block {
flex-direction: column;
align-items: stretch;
}
.cta-content {
text-align: center;
}
.cta-actions {
width: 100%;
}
}
Prompt this to your LLM
Includes role, constraints, two framework variants, and edge cases to handle.
You are a senior frontend engineer specializing in modern CSS layout.
Goal: Build a call-to-action (CTA) block component that adapts its layout based on available container width — no JavaScript.
Technical constraints:
- Use container-type: inline-size and @container queries to detect wrapper width.
- Structure: content area (heading + description) + action buttons (primary + secondary).
- Use oklch() for all colors — no hex or rgba().
- Layout shift: horizontal (side-by-side) when wide, vertical (stacked) when narrow.
- Include focus-visible styles for interactive elements (buttons).
Framework variant (pick one):
A) Vanilla HTML + CSS only.
B) React component — accept `title`, `description`, `primaryAction` (text + onClick), `secondaryAction` (text + onClick), `className` props; include CSS as a CSS module.
Edge cases to handle:
- Disabled state: add .disabled class with opacity: 0.6 and cursor: not-allowed on buttons.
- What happens if container queries are not supported? Provide a media query fallback.
- ARIA: ensure buttons have proper accessible names; add role="region" with aria-label if the CTA is standalone.
Return HTML + CSS, clearly separated.
Why this matters in 2026
CTA blocks appear everywhere — hero sections, sidebars, modals, email footers. Each context has different width constraints. Container queries let a single CTA component adapt: stacked in a narrow sidebar, horizontal in a wide hero. No more duplicate components or JS-driven class toggles.
This is component-driven responsive design at its best: the component knows its context and styles accordingly. Build once, embed anywhere.
The logic
container-type: inline-size on the wrapper establishes a sizing context. The @container cta (min-width: 20rem) rule checks that context, not the viewport. When the wrapper crosses the 20rem threshold, the block switches from stacked to side-by-side via flex-direction.
The breakpoint: 20rem ensures enough horizontal space for the content and buttons to sit comfortably side-by-side. Below that, stacking prevents cramped text and buttons.
Why container queries over media queries? A media query would respond to viewport width — useless when the same CTA appears in a narrow sidebar vs. a wide hero. Container queries make the CTA self-aware of its embedding context.
Accessibility & performance
CTA buttons must be keyboard-accessible with visible focus rings (:focus-visible). Use semantic HTML: wrap the CTA in <section> with aria-label if it's standalone. For performance, container queries run on the compositor thread — no layout thrashing. Avoid animating flex-direction (it's not animatable); instead, use @media (prefers-reduced-motion: reduce) to skip any transition effects.
@media (min-width: 20rem) fallback that assumes the wide layout.