Mappa Via Marconi 20, Bussolengo (VR)
Email info@devinterface.com

Advanced responsive design: from Media Queries to Container Queries

Index

For years, responsive design has been synonymous with Media Queries: breakpoints, viewports and adaptation to screen size. But the web has evolved, and with it our design needs. Thanks to Container Queries, we can now create truly modular layouts that adapt not only to the device but also to the context in which each component is placed. This is a huge step forward towards more flexible, scalable design that is independent of the overall structure of the page.

Media Queries

Media queries vs container queries

Media queries query monitor properties to adapt to both mobile devices and large desktop monitors. They combine CSS properties with logical queries on device properties.

Unlike container queries, media queries control layout and styles based on viewport size (i.e. based on the width of the browser window).

How big is the browser window?

Media queries primarily define CSS properties based on the height, width, or orientation (portrait or landscape) of the viewport or browser window. Only CSS properties that are applied when the condition is met are specified within the curly brackets of the @media rules.

@media (min-width: 480px) {
	main { width: 89%; }
}
This means that if the browser window is at least 480px wide, then the main occupies 89% of the available width.

Browsers understand queries relating to the size, orientation and resolution of the monitor or browser window.

/* Small screens: vertical layout */
.responsive-grid {
	display: grid;
	font-family: Arial, sans-serif;
	grid-gap: 10px;
}

/* Medium screens: 2 columns */
@media (min-width: 700px) {
	.responsive-grid {
		grid-template-areas:
			"box1 box2"
			"box3 box4"
			"box5 box6";
	}
}

/* Large screens: 3 columns */
@media (min-width: 1200px) {
	.responsive-grid {
		grid-template-areas:
			"box1 box1 box1"
			"box2 box3 box4"
			"box5 box5 box4"
			"box6 box6 box4";
	}
}

How are media queries used?

The standard layout for responsive websites is as follows: on smaller monitors, content is arranged linearly without positioning between elements. Websites are already responsive by default, provided that CSS does not position the elements. Only CSS for larger monitors positions blocks of elements next to each other.

Media queries require not only the resolution, size and orientation of the viewport, but also, for example, the visitor's day or night mode:

@media (prefers-color-scheme: dark) {
	body {
		background-color: #2a3b2a;
		color: #e0e0e0;
	}
}
the output mode (screen or print):

@media print {
	body {
		font-size: 13pt;
		font-family: Georgia, serif;
	}
}
and the device's capabilities (hover, touch, etc.):

@media (hover: hover) {
	button {
		background-color: lightsteelblue;
		color: darkslategray;
		transition: background-color 0.3s;
	}
	button:hover {
		background-color: steelblue;
	}
}

Multimedia rules and breakpoints

A @media rule defines a breakpoint, which is a point of interruption or a condition where the layout changes to better suit a class of devices. CSS properties that are not contained in a @media rule apply to all classes of devices and are primarily intended for smaller devices (mainly smartphones). From there, additional breakpoints define CSS properties for larger viewports.

Media queries only override properties that change or are added at a breakpoint.
A responsive design not only adapts to smartphone monitors, but also offers a coordinated design for different browser windows (viewports): added value for large monitors and a compact design for small browser windows.

Media query structure 

Media queries allow you to apply different CSS rules depending on the type of device and its characteristics (such as width, resolution, orientation, etc.).

Today, there are many classes of devices: smartphones, tablets, laptops, and large monitors. For each of these ‘classes,’ we can define a dedicated style sheet or specific CSS rules.

In the <link> tag of the HTML file, we can indicate a condition using the media attribute, which specifies when that style sheet should be loaded.

<link rel="stylesheet" href="base.css" media="all">
<link rel="stylesheet" href="tablet.css" media="(min-width: 700px)">
<link rel="stylesheet" href="desktop.css" media="(min-width: 1100px)">
<link rel="stylesheet" href="print.css" media="print">
It is also possible to write the conditions directly in the CSS file, without creating separate files. The use of only serves to exclude older browsers that do not support Media Queries - so they ignore the rule instead of misinterpreting it.

@media only screen and (min-width: 44em) and (max-width: 68em) {
  /* approximately 704px – 1088px → typical range for tablets */
  main {
    max-width: 90%;
    margin: 0 auto;
    font-size: 1.1rem;
  }
  .sidebar {
    display: none;
  }
}

The Viewport of mobile devices

Devices such as smartphones and tablets do not display their actual resolution in pixels. They pretend to have a much smaller width, for example 320px or 420px, even though the physical screen has many more pixels.

Let's take an example: the iPhone 11 has a physical screen resolution of 828 x 1792 pixels, but it tells the browser that the window (the viewport) measures only 414 x 896 pixels. 

This happens because modern screens (such as Retina Displays) have a much higher pixel density than normal monitors. Each CSS pixel actually corresponds to multiple physical pixels (often 2 or 3). 

The browser therefore automatically resizes (zooms) the page: it reduces the scale of the content so that the entire width of the page fits on the screen, allowing the user to see the entire site immediately, without having to scroll horizontally.

Let's take another example: Google Pixel 8 has a 6.2-inch screen with a screen size (resolution) of 1080px × 2400px. However, the browser says it only has 412px × 915px as a “logical” viewport. This happens because each CSS pixel corresponds to approximately 2.6 physical pixels.

When a web page is opened, the phone automatically resizes it (zoom out), adapts it to the width of the screen and then allows you to zoom in if you want to read it better.

In HTML files, the viewport meta tag is often used to control this behaviour:

<meta name="viewport" content="width=device-width, initial-scale=1.0">
width=device-width tells the browser to use the actual width of the device (in CSS pixels).
initial-scale=1.0 displays the page without initial zooming, at its natural scale.

If this tag is not present, the mobile browser ‘pretends’ that the page is 980px wide (or more) and reduces it to fit the screen, often resulting in it being too small.


Container Queries

Imagine you have a card set up according to the media query. This method works perfectly, as long as the card occupies the entire screen. But what happens if the same card is located in a narrow sidebar? Or in a grid layout with limited space? The result is often a fragmented design that does not fit its container. This is where container queries come into play.

With container queries, an element adapts to the width of its main container and not to the width of the viewport, as is the case with media queries. This is perfect for modular and reusable components.

As an example, consider blog post excerpts that are placed in a sidebar or grid layout. The arrangement of blog posts in the grid on the home page relative to the sidebar also falls into this category. Typically, the layout displays cards and their content in rows one below the other in narrow viewports, and only in wider viewports are two or more cards placed side by side. When two or more cards appear side by side, the images become oversized: in this case, it is more efficient to place the card content side by side as well.

Unlike media queries, container queries react to the dimensions of the parent container, not the entire viewport.

Key concepts for container queries

1. A container must be explicitly defined with container-type. No additional wrapper is required, provided that container-type is set on an ancestor.

.article-container {
	container-type: inline-size;
	padding: 16px;
	width: 100%;
	max-width: 940px;
	background-color: #e0e0e0;
	border-radius: 8px;
}
inline-size measures the width (in the direction of writing, so usually horizontally). Container queries only measure the size of the next contained container, not that of the viewport.

2. Moreover, it is possible to set container-name to access the container in a targeted manner.

.content-box {
	container-type: inline-size;
	container-name: article;
}
3. The container query is similar to a @media query:

@container (min-width: 420px) {
	.article {
		display: grid;
		grid-template-columns: 2fr 3fr;
		grid-template-areas: 
			"title title"
			"media text";
		gap: 1.2rem;
		align-items: start;
	}
}
or with a name

@container article (min-width: 420px) {
	/* Rules applied to elements within the ‘article’ container */
}
4. Container queries only affect elements within the defined container.

Cards

The layout of product cards and blog post excerpts arranges the cards/excerpts one below the other until there is enough space on a larger monitor to display two or more cards side by side.
If these layout elements are not only found in the main area of the page, but also appear in sidebars or footers, container queries are also used.

/* Main containers (section and aside) */
.main-section,
.side-panel {
	min-width: 150px;
	container-type: inline-size;
	container-name: gallery;
}

/* From 480px upwards → 2 cards per row */
@container gallery (min-width: 480px) {
	.card-list {
		display: flex;
		flex-wrap: wrap;
		gap: 1rem;
	}

	.card-item {
		flex: 1 1 calc(50% - 1rem);
	}
}

/* From 900px upwards → 3 cards per row */
@container gallery (min-width: 900px) {
	.card-item {
		flex: 1 1 calc(33.333% - 1rem);
	}
}

Is it possible to use container queries in <img> tags for dimensions?

There are situations where Media Queries (@media) cannot be replaced by Container Queries (@container).
One of these is inside the <img> tag, in the srcset and sizes attributes.

When the browser reads the HTML, it immediately chooses which image to load (based on srcset and sizes). This happens before CSS is applied, so Container Queries are not yet “active”.

Therefore, writing something like:

sizes="container(max-width: 600px) 420px, 920px"
it does not work because the sizes attribute does not understand what a container is.

If an image can fit into containers of different sizes (e.g. 920px or 1440px), you cannot ask the browser to adapt to the container. Instead, you must:

  • use multiple <img> tags for different situations (e.g. a wider image and a narrower one)
  • or manage everything with @media queries in CSS, which look at the width of the viewport (not the container).

Conclusion

The introduction of Container Queries marks a new era for responsive design. We are no longer constrained by screen width, but can finally think in terms of adaptive components. This paradigm shift allows us to build more consistent, maintainable and truly future-proof interfaces. 

Responsive design is no longer just a technique: it has become a universal design principle, centred on flexibility and intelligent layout.