Container queries represent one of the most significant advances in CSS responsive design since media queries were introduced. For WordPress developers, they solve long-standing challenges with component-based layouts, block themes, and widget responsiveness. This comprehensive guide will show you how to implement container queries in WordPress theme development, transforming how your themes adapt to different contexts.
Why Container Queries Are Game-Changers for WordPress
The Viewport Problem
Traditional media queries base their decisions on viewport dimensions, but modern WordPress sites are component-driven. Consider a common scenario: you’ve created a beautiful blog post card component that works perfectly in your main content area. But when the same component appears in a narrow sidebar widget, it breaks completely because the media query still thinks it has full viewport width to work with.
This viewport-centric approach creates numerous problems in WordPress development:
- Sidebar widgets that assume full-width contexts and break in narrow containers
- Gutenberg blocks that can’t adapt when placed in columns or group blocks
- Plugin widgets that look perfect in wide areas but cramped in narrow sidebars
- Responsive layouts that require multiple component variations for different contexts
What Are Container Queries
Container queries shift the responsive paradigm from viewport-based decisions to container-based decisions. Instead of asking “how wide is the browser?”, container queries ask “how wide is this component’s container?”. This fundamental shift enables true component-level responsiveness.
In WordPress terms, this means:
- A post card can adapt differently when placed in the main content area versus a sidebar
- Gutenberg blocks can respond to their immediate container, not the entire page
- WooCommerce product grids can optimize their layout based on available space
- Navigation menus can switch layouts based on header container width
Browser Support Status (2025)
As of 2025, container queries have excellent browser support:
- Chrome/Edge: Full support since version 105
- Firefox: Full support since version 110
- Safari: Full support since version 16
This widespread support makes container queries production-ready for most WordPress sites, with progressive enhancement strategies available for older browsers. We previously had issues with this when dealing with a newssite like NordNews.dk but now the issue has been solved.
Understanding Container Queries vs Media Queries
Media Query Limitations in WordPress
Let’s examine a typical WordPress challenge. You have a post card component that needs to work in multiple contexts:
css
/* Traditional media query approach */
.post-card {
display: flex;
flex-direction: row;
}
.post-card .featured-image {
width: 40%;
}
.post-card .content {
width: 60%;
padding: 1rem;
}
/* This breaks in narrow sidebars! */
@media (max-width: 768px) {
.post-card {
flex-direction: column;
}
.post-card .featured-image,
.post-card .content {
width: 100%;
}
}
The problem: this media query triggers based on viewport width, not the actual space available to the component. A post card in a 300px sidebar will maintain its horizontal layout even when the viewport is 1200px wide, creating a cramped, unusable interface.
Container Query Advantages
Container queries solve this by responding to the container’s dimensions:
css
/* Container query approach */
.post-card-container {
container-type: inline-size;
container-name: post-card;
}
.post-card {
display: flex;
flex-direction: row;
}
.post-card .featured-image {
width: 40%;
}
.post-card .content {
width: 60%;
padding: 1rem;
}
/* Responds to container width, not viewport */
@container post-card (max-width: 400px) {
.post-card {
flex-direction: column;
}
.post-card .featured-image,
.post-card .content {
width: 100%;
}
}
Now the same component adapts perfectly whether it’s in the main content area, a sidebar, or anywhere else, based purely on available space.
Setting Up Container Queries in WordPress
Browser Support Check and Progressive Enhancement
Before implementing container queries, establish a progressive enhancement strategy:
php
// functions.php
function theme_supports_container_queries() {
// Feature detection via CSS @supports
wp_add_inline_style(‘theme-style’, ‘
@supports (container-type: inline-size) {
.supports-container-queries {
display: block;
}
}
.supports-container-queries {
display: none;
}
‘);
}
add_action(‘wp_enqueue_scripts’, ‘theme_supports_container_queries’);
CSS Setup in WordPress Themes
Create a dedicated stylesheet for container queries:
php
// functions.php
function enqueue_container_query_styles() {
wp_enqueue_style(
‘theme-container-queries’,
get_template_directory_uri() . ‘/css/container-queries.css’,
array(‘theme-style’),
wp_get_theme()->get(‘Version’)
);
}
add_action(‘wp_enqueue_scripts’, ‘enqueue_container_query_styles’);
WordPress Theme Integration
Structure your theme templates to support containers:
php
<!– content-card.php –>
<article class=”post-card-container”>
<div class=”post-card”>
<?php if (has_post_thumbnail()): ?>
<div class=”featured-image”>
<?php the_post_thumbnail(‘medium’); ?>
</div>
<?php endif; ?>
<div class=”content”>
<h3><a href=”<?php the_permalink(); ?>”><?php the_title(); ?></a></h3>
<div class=”excerpt”><?php the_excerpt(); ?></div>
<div class=”meta”>
<time><?php echo get_the_date(); ?></time>
<span class=”author”><?php the_author(); ?></span>
</div>
</div>
</div>
</article>
WordPress-Specific Container Query Patterns
Gutenberg Block Responsiveness
Modern WordPress relies heavily on the block editor. Container queries enable blocks to adapt to their immediate context:
css
/* Block container setup */
.wp-block-group,
.wp-block-columns .wp-block-column {
container-type: inline-size;
}
/* Responsive heading block */
.wp-block-heading {
font-size: 2rem;
line-height: 1.2;
}
@container (max-width: 400px) {
.wp-block-heading {
font-size: 1.5rem;
}
}
@container (max-width: 250px) {
.wp-block-heading {
font-size: 1.25rem;
line-height: 1.3;
}
}
Widget and Sidebar Applications
Transform WordPress widgets to be truly responsive:
css
/* Widget container setup */
.widget {
container-type: inline-size;
container-name: widget;
}
/* Responsive recent posts widget */
.widget_recent_entries ul {
display: grid;
gap: 1rem;
grid-template-columns: 1fr;
}
@container widget (min-width: 300px) {
.widget_recent_entries ul {
grid-template-columns: 1fr 1fr;
}
}
@container widget (min-width: 500px) {
.widget_recent_entries ul {
grid-template-columns: repeat(3, 1fr);
}
}
/* Responsive search widget */
.widget_search form {
display: flex;
flex-direction: column;
gap: 0.5rem;
}
@container widget (min-width: 250px) {
.widget_search form {
flex-direction: row;
}
.widget_search input[type=”search”] {
flex: 1;
}
}
Post Content Layouts
Create adaptive content layouts that work in any context:
css
/* Post content container */
.entry-content {
container-type: inline-size;
}
/* Responsive image alignments */
.entry-content .alignright,
.entry-content .alignleft {
max-width: 50%;
margin: 0 0 1rem 1rem;
}
@container (max-width: 600px) {
.entry-content .alignright,
.entry-content .alignleft {
float: none;
max-width: 100%;
margin: 1rem 0;
}
}
/* Responsive gallery layouts */
.wp-block-gallery {
display: grid;
gap: 1rem;
grid-template-columns: 1fr;
}
@container (min-width: 400px) {
.wp-block-gallery {
grid-template-columns: 1fr 1fr;
}
}
@container (min-width: 600px) {
.wp-block-gallery {
grid-template-columns: repeat(3, 1fr);
}
}
@container (min-width: 800px) {
.wp-block-gallery {
grid-template-columns: repeat(4, 1fr);
}
}
Advanced Container Query Techniques
Container Query Units
Container queries introduce new units that scale with container dimensions:
- cqw: 1% of the container’s width
- cqh: 1% of the container’s height
- cqi: 1% of the container’s inline size
- cqb: 1% of the container’s block size
css
/* Typography that scales with container */
.dynamic-text {
font-size: clamp(1rem, 4cqw, 3rem);
line-height: 1.2;
}
/* Container-relative spacing */
.card-content {
padding: 2cqi;
margin-bottom: 3cqb;
}
/* Responsive icons */
.icon {
width: 8cqi;
height: 8cqi;
min-width: 24px;
min-height: 24px;
}
Multiple Container Contexts
WordPress themes often need multiple container contexts:
css
/* Named containers for different contexts */
.main-content {
container-type: inline-size;
container-name: main;
}
.sidebar {
container-type: inline-size;
container-name: sidebar;
}
.footer-widgets {
container-type: inline-size;
container-name: footer;
}
/* Context-specific styling */
@container main (min-width: 800px) {
.post-grid {
grid-template-columns: repeat(3, 1fr);
}
}
@container sidebar (min-width: 300px) {
.post-grid {
grid-template-columns: 1fr;
}
}
@container footer (min-width: 600px) {
.post-grid {
grid-template-columns: 1fr 1fr;
}
}
WordPress Navigation Enhancement
Create truly responsive navigation systems:
css
/* Navigation container */
.main-navigation {
container-type: inline-size;
container-name: nav;
}
/* Default horizontal layout */
.nav-menu {
display: flex;
flex-wrap: wrap;
gap: 1rem;
}
.nav-menu a {
padding: 0.5rem 1rem;
text-decoration: none;
border-radius: 4px;
}
/* Compact layout for narrow containers */
@container nav (max-width: 600px) {
.nav-menu {
flex-direction: column;
gap: 0.5rem;
}
.nav-menu a {
padding: 0.75rem 1rem;
border-bottom: 1px solid #eee;
border-radius: 0;
}
}
/* Dropdown for very narrow containers */
@container nav (max-width: 400px) {
.nav-menu {
position: relative;
}
.nav-menu::before {
content: “Menu”;
display: block;
padding: 1rem;
background: #f8f9fa;
cursor: pointer;
}
.nav-menu:not(:hover) .menu-item:not(:first-child) {
display: none;
}
.nav-menu:hover .menu-item {
display: block;
}
}
Practical WordPress Implementation Examples
Blog Layout Components
Here’s a complete implementation of adaptive post cards:
php
<!– template-parts/content-card.php –>
<article class=”post-card-container” <?php post_class(); ?>>
<div class=”post-card”>
<?php if (has_post_thumbnail()): ?>
<div class=”post-thumbnail”>
<a href=”<?php the_permalink(); ?>”>
<?php the_post_thumbnail(‘medium’); ?>
</a>
</div>
<?php endif; ?>
<div class=”post-content”>
<header class=”entry-header”>
<h2 class=”entry-title”>
<a href=”<?php the_permalink(); ?>”><?php the_title(); ?></a>
</h2>
<div class=”entry-meta”>
<time class=”published” datetime=”<?php echo get_the_date(‘c’); ?>”>
<?php echo get_the_date(); ?>
</time>
<span class=”author”>by <?php the_author(); ?></span>
</div>
</header>
<div class=”entry-excerpt”>
<?php the_excerpt(); ?>
</div>
<footer class=”entry-footer”>
<a href=”<?php the_permalink(); ?>” class=”read-more”>
Read More
</a>
<div class=”post-categories”>
<?php the_category(‘, ‘); ?>
</div>
</footer>
</div>
</div>
</article>
css
/* Post card container queries */
.post-card-container {
container-type: inline-size;
container-name: post-card;
margin-bottom: 2rem;
}
/* Default layout – horizontal */
.post-card {
display: flex;
gap: 1.5rem;
padding: 1.5rem;
background: #fff;
border-radius: 8px;
box-shadow: 0 2px 8px rgba(0,0,0,0.1);
transition: box-shadow 0.3s ease;
}
.post-card:hover {
box-shadow: 0 4px 16px rgba(0,0,0,0.15);
}
.post-thumbnail {
flex-shrink: 0;
width: 200px;
}
.post-thumbnail img {
width: 100%;
height: 150px;
object-fit: cover;
border-radius: 4px;
}
.post-content {
flex: 1;
display: flex;
flex-direction: column;
}
.entry-title {
margin: 0 0 0.5rem 0;
font-size: 1.25rem;
line-height: 1.3;
}
.entry-title a {
color: #333;
text-decoration: none;
}
.entry-title a:hover {
color: #0073aa;
}
.entry-meta {
margin-bottom: 1rem;
font-size: 0.875rem;
color: #666;
}
.entry-excerpt {
flex: 1;
margin-bottom: 1rem;
line-height: 1.6;
}
.entry-footer {
display: flex;
justify-content: space-between;
align-items: center;
}
.read-more {
color: #0073aa;
text-decoration: none;
font-weight: 500;
}
.post-categories {
font-size: 0.875rem;
}
/* Medium containers – stack vertically */
@container post-card (max-width: 500px) {
.post-card {
flex-direction: column;
gap: 1rem;
}
.post-thumbnail {
width: 100%;
}
.post-thumbnail img {
height: 200px;
}
.entry-footer {
flex-direction: column;
gap: 0.5rem;
align-items: flex-start;
}
}
/* Small containers – compact layout */
@container post-card (max-width: 350px) {
.post-card {
padding: 1rem;
gap: 0.75rem;
}
.entry-title {
font-size: 1.1rem;
}
.post-thumbnail img {
height: 150px;
}
.entry-meta {
margin-bottom: 0.75rem;
}
}
WooCommerce Integration
Container queries work excellently with WooCommerce product displays:
css
/* Product grid container */
.woocommerce .products {
container-type: inline-size;
display: grid;
gap: 1.5rem;
grid-template-columns: 1fr;
}
@container (min-width: 400px) {
.woocommerce .products {
grid-template-columns: 1fr 1fr;
}
}
@container (min-width: 600px) {
.woocommerce .products {
grid-template-columns: repeat(3, 1fr);
}
}
@container (min-width: 900px) {
.woocommerce .products {
grid-template-columns: repeat(4, 1fr);
}
}
/* Individual product containers */
.woocommerce ul.products li.product {
container-type: inline-size;
container-name: product;
}
/* Product layout adaptations */
.woocommerce .product .woocommerce-loop-product__title {
font-size: 1rem;
margin: 0.5rem 0;
}
@container product (max-width: 200px) {
.woocommerce .product .woocommerce-loop-product__title {
font-size: 0.875rem;
line-height: 1.3;
}
.woocommerce .product .price {
font-size: 0.875rem;
}
}
@container product (min-width: 300px) {
.woocommerce .product .woocommerce-loop-product__title {
font-size: 1.125rem;
margin: 0.75rem 0;
}
}
Performance and Optimization
Container Query Performance
Container queries are generally performant, but follow these best practices:
css
/* Efficient container setup */
.container {
/* Use inline-size for width-based queries */
container-type: inline-size;
/* Avoid size if you don’t need height queries */
/* container-type: size; /* Can impact performance */
}
/* Minimize container query nesting */
@container (min-width: 400px) {
.component {
/* Direct styling is faster than nested queries */
grid-template-columns: 1fr 1fr;
}
/* Avoid deep nesting when possible */
@container (min-width: 600px) {
.component {
grid-template-columns: repeat(3, 1fr);
}
}
}
WordPress Caching Considerations
Container queries are CSS-based, so they work well with WordPress caching:
php
// functions.php – Optimize CSS delivery
function optimize_container_query_css() {
if (is_admin()) return;
// Inline critical container query CSS
$critical_css = ‘
.main-container { container-type: inline-size; }
.sidebar { container-type: inline-size; }
‘;
wp_add_inline_style(‘theme-style’, $critical_css);
}
add_action(‘wp_enqueue_scripts’, ‘optimize_container_query_css’);
Fallback Strategies
Ensure graceful degradation for older browsers:
css
/* Progressive enhancement approach */
.component {
/* Default layout for all browsers */
display: block;
}
/* Enhanced layout with feature detection */
@supports (container-type: inline-size) {
.container {
container-type: inline-size;
}
.component {
display: flex;
}
@container (min-width: 400px) {
.component {
flex-direction: row;
}
}
}
/* Fallback using JavaScript if needed */
@supports not (container-type: inline-size) {
.js-fallback-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
}
}
Debugging and Testing
Browser Developer Tools
Modern browsers provide excellent container query debugging:
- Chrome DevTools: Look for the “Container” badge next to elements
- Inspect container queries in the Styles panel
- Test different container sizes using the device toolbar
- Monitor layout shifts in the Performance tab
WordPress-Specific Testing
Create a comprehensive testing strategy:
php
// Test helper – Add to functions.php during development
function container_query_debug() {
if (!current_user_can(‘manage_options’)) return;
wp_add_inline_style(‘theme-style’, ‘
[style*=”container-type”] {
outline: 2px dashed red;
position: relative;
}
[style*=”container-type”]::before {
content: “Container: ” attr(style);
position: absolute;
top: -20px;
left: 0;
background: red;
color: white;
font-size: 10px;
padding: 2px 4px;
z-index: 1000;
}
‘);
}
// add_action(‘wp_enqueue_scripts’, ‘container_query_debug’); // Uncomment to debug
Future-Proofing Your WordPress Theme
Upcoming Container Query Features
Stay ahead of the curve with emerging features:
- Style queries: Query based on CSS property values, not just dimensions
- Container query lengths: More precise container-relative units
- Scroll-state queries: Respond to container scroll position
css
/* Future style queries (experimental) */
@supports (container-type: style) {
@container style(background-color: dark) {
.content {
color: white;
}
}
}
WordPress Core Integration
WordPress is gradually improving container query support:
php
// Theme.json support (WordPress 6.1+)
{
“version”: 2,
“settings”: {
“layout”: {
“contentSize”: “800px”,
“wideSize”: “1200px”
},
“custom”: {
“containerQueries”: {
“enabled”: true
}
}
}
}
Migration Strategies
Convert existing themes incrementally:
- Start with components: Begin with widgets and post cards
- Add progressive enhancement: Keep existing media queries as fallbacks
- Test thoroughly: Ensure compatibility across browsers and devices
- Document changes: Help future developers understand the implementation
Implementation Roadmap
Phase 1: Foundation (Week 1)
- Set up container query CSS architecture
- Implement basic container types in key areas
- Test browser support and fallbacks
Phase 2: Components (Weeks 2-3)
- Convert post cards and widgets
- Implement Gutenberg block responsiveness
- Add navigation enhancements
Phase 3: Advanced Features (Week 4)
- Implement container query units
- Add multiple container contexts
- Optimize performance and caching
Phase 4: Polish and Testing (Week 5)
- Cross-browser testing
- Accessibility verification
- Documentation and handoff
Conclusion
Container queries represent a paradigm shift in responsive design, particularly valuable for WordPress’s component-driven architecture. By implementing container queries in your WordPress themes, you create truly adaptive components that work perfectly regardless of their context.
The key benefits include:
- True component responsiveness that adapts to container size, not viewport
- Better Gutenberg integration with blocks that respond to their immediate context
- Simplified maintenance with fewer breakpoint variations needed
- Future-proof architecture that leverages modern CSS capabilities
Start with simple implementations like post cards and widgets, then gradually expand to more complex layouts. With careful implementation and thorough testing, container queries will transform how your WordPress themes handle responsive design.
Remember to maintain progressive enhancement principles, ensure accessibility compliance, and thoroughly test across different browsers and devices. Container queries are not just a new CSS feature – they’re a fundamental improvement in how we think about responsive design in WordPress.
The future of WordPress theme development is container-aware, and now you have the knowledge to build themes that truly adapt to any context.
Additional Resources