Index
Media Queries
Media queries vs container queries
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 (min-width: 480px) {
main { width: 89%; }
}
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?
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;
}
}
@media print {
body {
font-size: 13pt;
font-family: Georgia, serif;
}
}
@media (hover: hover) {
button {
background-color: lightsteelblue;
color: darkslategray;
transition: background-color 0.3s;
}
button:hover {
background-color: steelblue;
}
}
Multimedia rules and breakpoints
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
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">
@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
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">
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
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
.article-container {
container-type: inline-size;
padding: 16px;
width: 100%;
max-width: 940px;
background-color: #e0e0e0;
border-radius: 8px;
}
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;
}
@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;
}
}
@container article (min-width: 420px) {
/* Rules applied to elements within the ‘article’ container */
}
Cards
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?
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"
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
Responsive design is no longer just a technique: it has become a universal design principle, centred on flexibility and intelligent layout.