Container query
Container queries are a powerful feature in CSS3 that allow developers to apply styles based on the dimensions of an element itself rather than the viewport. They address the limitations of media queries, enabling components to adapt more flexibly to different container environments and truly achieve modular design.
Basic Syntax of Container Queries
The core of container queries is defining the scope of styles using the @container
rule. First, the parent element must be declared as a container, and then child elements can adjust their styles based on the container's dimensions:
.parent {
container-type: inline-size; /* Declare as an inline-size container */
}
@container (min-width: 400px) {
.child {
font-size: 1.2rem;
}
}
There are three possible values for container types:
size
: Monitors both width and height changesinline-size
: Monitors only the inline dimension (typically width)normal
: Not a sizing container but still supports style queries
Practical Use Cases
Adaptive Card Components
With traditional media queries, all cards change styles simultaneously. Container queries allow each card to respond independently to its container's dimensions:
<div class="card-container">
<div class="card">...</div>
</div>
<style>
.card-container {
container-type: inline-size;
}
/* Narrow container styles */
@container (max-width: 300px) {
.card {
flex-direction: column;
}
}
/* Medium container styles */
@container (300px < width < 500px) {
.card {
grid-template-columns: 120px 1fr;
}
}
/* Wide container styles */
@container (min-width: 500px) {
.card {
display: flex;
align-items: center;
}
}
Responsive Navigation Menu
A navigation menu can automatically switch display modes based on its parent container's width:
.nav-container {
container-type: inline-size;
}
@container (width < 600px) {
.nav-menu {
flex-direction: column;
}
.nav-item {
padding: 8px 0;
}
}
@container (width >= 600px) {
.nav-menu {
display: flex;
gap: 1rem;
}
}
Container Query Units
CSS3 introduces relative units specifically for container queries:
cqw
: 1% of the container's widthcqh
: 1% of the container's heightcqi
: 1% of the container's inline sizecqb
: 1% of the container's block sizecqmin
: The smaller ofcqi
andcqb
cqmax
: The larger ofcqi
andcqb
.component {
/* Font size scales with container width */
font-size: clamp(1rem, 3cqw, 1.5rem);
/* Padding uses the smaller of width or height */
padding: calc(2 * cqmin);
}
Comparison with Media Queries
Media queries are based on viewport dimensions and are suitable for global layout adjustments, while container queries target specific components for finer control:
/* Media query - global responsiveness */
@media (max-width: 768px) {
.sidebar {
display: none;
}
}
/* Container query - component-level responsiveness */
.sidebar-wrapper {
container-type: inline-size;
}
@container (width < 200px) {
.sidebar {
transform: translateX(-100%);
}
}
Performance Optimization Tips
- Avoid excessive nesting: Container queries create new stacking contexts, and deep nesting may impact performance.
- Choose container types wisely: Prefer
inline-size
oversize
to reduce unnecessary reflows. - Limit the number of query conditions: Each
@container
rule adds to style calculation overhead.
/* Not recommended */
@container (width > 100px) and (width < 300px) and (height > 50px) {
/* Complex styles */
}
/* Recommended */
@container (100px < width < 300px) {
/* Simplified conditions */
}
Browser Compatibility Handling
While modern browsers widely support container queries, fallback solutions are needed for older browsers:
.card {
/* Base styles */
display: block;
}
@supports (container-type: inline-size) {
.card-container {
container-type: inline-size;
}
@container (width > 400px) {
.card {
display: flex;
}
}
}
Advanced Usage Examples
Dynamic Adjustments with CSS Variables
:root {
--card-ratio: 1;
}
.card-container {
container-type: size;
}
@container (aspect-ratio > 1) {
.card {
--card-ratio: 1.5;
grid-template-columns: 1fr 2fr;
}
}
.card-image {
flex-grow: var(--card-ratio);
}
Nested Container Queries
.grid {
container-type: inline-size;
}
.grid-item {
container-type: inline-size;
}
@container (width > 300px) {
.grid {
grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
}
@container (width > 150px) {
.grid-item {
border-radius: 8px;
}
}
}
Debugging Tips
- In Chrome DevTools, enable container query debugging flags via
Settings > Experiments
. - Use the
outline
property to highlight container boundaries:
[style*="container-type"] {
outline: 2px dashed rgba(255,0,0,0.3);
}
- Detect container states via JavaScript:
const observer = new ResizeObserver(entries => {
entries.forEach(entry => {
console.log(entry.contentBoxSize);
});
});
observer.observe(document.querySelector('.container'));
本站部分内容来自互联网,一切版权均归源网站或源作者所有。
如果侵犯了你的权益请来信告知我们删除。邮箱:cc@cccx.cn
上一篇:原生嵌套规则
下一篇:层叠层(@layer)