1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
|
---
title: Guide du débutant des Media Queries
slug: Learn/CSS/CSS_layout/Media_queries
translation_of: Learn/CSS/CSS_layout/Media_queries
original_slug: Apprendre/CSS/CSS_layout/Media_queries
---
<p>{{learnsidebar}}{{PreviousMenuNext("Learn/CSS/CSS_layout/Responsive_Design", "Learn/CSS/CSS_layout/Legacy_Layout_Methods", "Learn/CSS/CSS_layout")}}</p>
<p>The <strong>CSS Media Query</strong> gives you a way to apply CSS only when the browser and device environment matches a rule that you specify, for example "viewport is wider than 480 pixels". Media queries are a key part of responsive web design, as they allow you to create different layouts depending on the size of the viewport, but they can also be used to detect other things about the environment your site is running on, for example whether the user is using a touchscreen rather than a mouse. In this lesson you will first learn about the syntax used in media queries, and then move on to use them in a worked example showing how a simple design might be made responsive.</p>
<table class="learn-box standard-table">
<tbody>
<tr>
<th scope="row">Prerequisites:</th>
<td>HTML basics (study <a href="/en-US/docs/Learn/HTML/Introduction_to_HTML">Introduction to HTML</a>), and an idea of how CSS works (study <a href="/en-US/docs/Learn/CSS/First_steps">CSS first steps</a> and <a href="/en-US/docs/Learn/CSS/Building_blocks">CSS building blocks</a>.)</td>
</tr>
<tr>
<th scope="row">Objective:</th>
<td>To understand how to use media queries, and the most common approach for using them to create responsive designs.</td>
</tr>
</tbody>
</table>
<h2 id="Media_Query_Basics">Media Query Basics</h2>
<p>The simplest media query syntax looks like this:</p>
<pre class="brush: css">@media <em>media-type</em> and (<em>media-feature-rule</em>) {
/* CSS rules go here */
}</pre>
<p>It consists of:</p>
<ul>
<li>A media type, which tells the browser what kind of media this code is for (e.g. print, or screen).</li>
<li>A media expression, which is a rule, or test that must be passed for the contained CSS to be applied.</li>
<li>A set of CSS rules that will be applied if the test passes and the media type is correct.</li>
</ul>
<h3 id="Media_types">Media types</h3>
<p>The possible types of media you can specify are:</p>
<ul>
<li><code>all</code></li>
<li><code>print</code></li>
<li><code>screen</code></li>
<li><code>speech</code></li>
</ul>
<p>The following media query will only set the body to 12pt if the page is printed. It will not apply when the page is loaded in a browser.</p>
<pre class="brush: css"><code>@media print {
body {
font-size: 12pt;
}
}</code></pre>
<div class="blockIndicator note">
<p><strong>Note</strong>: the media type here is different from the so-called {{glossary("MIME type")}}.</p>
</div>
<div class="blockIndicator note">
<p><strong>Note</strong>: there were a number of other media types defined in the Level 3 Media Queries specification; these have been deprecated and should be avoided.</p>
</div>
<div class="blockIndicator note">
<p><strong>Note</strong>: Media types are optional; if you do not indicate a media type in your media query then the media query will default to being for all media types.</p>
</div>
<h3 id="Media_feature_rules">Media feature rules</h3>
<p>After specifying the type, you can then target a media feature with a rule.</p>
<h4 id="Width_and_height">Width and height</h4>
<p>The feature we tend to detect most often in order to create responsive designs (and that has widespread browser support) is viewport width, and we can apply CSS if the viewport is above or below a certain width — or an exact width — using the <code>min-width</code>, <code>max-width</code>, and <code>width</code> media features.</p>
<p>These features are used to create layouts that respond to different screen sizes. For example, to change the body text color to red if the viewport is exactly 600 pixels, you would use the following media query.</p>
<pre class="brush: css"><code>@media screen and (width: 600px) {
body {
color: red;
}
}</code></pre>
<p><a href="https://mdn.github.io/css-examples/learn/media-queries/width.html">Open this example</a> in the browser, or <a href="https://github.com/mdn/css-examples/blob/master/learn/media-queries/width.html">view the source</a>.</p>
<p>The <code>width</code> (and <code>height</code>) media features can be used as ranges, and therefore be prefixed with <code>min-</code> or <code>max-</code> to indicate that the given value is a minimum, or a maximum. For example, to make the color blue if the viewport is narrower than 400 pixels, use <code>max-width</code>:</p>
<pre class="brush: css"><code>@media screen and (max-width: 400px) {
body {
color: blue;
}
}</code></pre>
<p><a href="https://mdn.github.io/css-examples/learn/media-queries/max-width.html">Open this example</a> in the browser, or <a href="https://github.com/mdn/css-examples/blob/master/learn/media-queries/max-width.html">view the source</a>.</p>
<p>In practice, using minimum or maximum values is much more useful for responsive design so you will rarely see <code>width</code> or <code>height</code> used alone.</p>
<p>There are a number of other media features that you can test for, although some of the newer features introduced in Level 4 and 5 of the media queries specification have limited browser support. Each feature is documented on MDN along with browser support information, and you can find a full list at <a href="/en-US/docs/Web/CSS/Media_Queries/Using_media_queries#Media_features">Using Media Queries: Media Features</a>.</p>
<h4 id="Orientation">Orientation</h4>
<p>One well-supported media feature is <code>orientation</code>, which allows us to test for portrait or landscape mode. To change the body text color if the device is in landscape orientation, use the following media query.</p>
<pre class="brush: css"><code>@media (orientation: landscape) {
body {
color: rebeccapurple;
}
}</code></pre>
<p><a href="https://mdn.github.io/css-examples/learn/media-queries/orientation.html">Open this example</a> in the browser, or <a href="https://github.com/mdn/css-examples/blob/master/learn/media-queries/orientation.html">view the source</a>.</p>
<p>A standard desktop view has a landscape orientation, and a design that works well in this orientation may not work as well when viewed on a phone or tablet in portrait mode. Testing for orientation can help you to create a layout which is optimised for devices in portrait mode.</p>
<h4 id="Use_of_pointing_devices">Use of pointing devices</h4>
<p>As part of the Level 4 specification, the <code>hover</code> media feature was introduced. This feature means you can test if the user has the ability to hover over an element, which essentially means they are using some kind of pointing device; touchscreen and keyboard navigation does not hover.</p>
<pre class="brush: css"><code>@media (hover: hover) {
body {
color: rebeccapurple;
}
}</code></pre>
<p><a href="https://mdn.github.io/css-examples/learn/media-queries/hover.html">Open this example</a> in the browser, or <a href="https://github.com/mdn/css-examples/blob/master/learn/media-queries/hover.html">view the source</a>.</p>
<p>If we know the user cannot hover, we could display some interactive features by default. For users who can hover, we might choose to make them available when a link is hovered over.</p>
<p>Also in Level 4 is the <code>pointer</code> media feature. This takes three possible values, <code>none</code>, <code>fine</code> and <code>coarse</code>. A <code>fine</code> pointer is something like a mouse or trackpad. It enables the user to precisely target a small area. A <code>coarse</code> pointer is your finger on a touchscreen. The value <code>none</code> means the user has no pointing device; perhaps they are navigating with the keyboard only or with voice commands.</p>
<p>Using <code>pointer</code> can help you to design better interfaces that respond to the type of interaction a user is having with a screen. For example, you could create larger hit areas if you know that the user is interacting with the device as a touchscreen.</p>
<h2 id="More_complex_media_queries">More complex media queries</h2>
<p>With all of the different possible media queries, you may want to combine them, or create lists of queries — any of which could be matched.</p>
<h3 id="and_logic_in_media_queries">"and" logic in media queries</h3>
<p>To combine media features you can use <code>and</code> in much the same way as we have used <code>and</code> above to combine a media type and feature. For example, we might want to test for a <code>min-width</code> and <code>orientation</code>. The body text will only be blue if the viewport is at least 400 pixels wide and the device is in landscape mode.</p>
<pre class="brush: css"><code>@media screen and (min-width: 400px) and (orientation: landscape) {
body {
color: blue;
}
}</code></pre>
<p><a href="https://mdn.github.io/css-examples/learn/media-queries/and.html">Open this example</a> in the browser, or <a href="https://github.com/mdn/css-examples/blob/master/learn/media-queries/and.html">view the source</a>.</p>
<h3 id="or_logic_in_media_queries">"or" logic in media queries</h3>
<p>If you have a set of queries, any of which could match, then you can comma separate these queries. In the below example the text will be blue if the viewport is at least 400 pixels wide OR the device is in landscape orientation. If either of these things are true the query matches.</p>
<pre class="brush: css"><code>@media screen and (min-width: 400px), screen and (orientation: landscape) {
body {
color: blue;
}
}</code></pre>
<p><a href="https://mdn.github.io/css-examples/learn/media-queries/or.html">Open this example</a> in the browser, or <a href="https://github.com/mdn/css-examples/blob/master/learn/media-queries/or.html">view the source</a>.</p>
<h3 id="not_logic_in_media_queries">"not" logic in media queries</h3>
<p>You can negate an entire media query by using the <code>not</code> operator. This reverses the meaning of the entire media query. Therefore in this next example the text will only be blue if the orientation is portrait.</p>
<pre class="brush: css"><code>@media not all and (orientation: landscape) {
body {
color: blue;
}
}</code></pre>
<p><a href="https://mdn.github.io/css-examples/learn/media-queries/not.html">Open this example</a> in the browser, or <a href="https://github.com/mdn/css-examples/blob/master/learn/media-queries/not.html">view the source</a>.</p>
<h2 id="How_to_choose_breakpoints">How to choose breakpoints</h2>
<p>In the early days of responsive design, many designers would attempt to target very specific screen sizes. Lists of the sizes of the screens of popular phones and tablets were published in order that designs could be created to neatly match those viewports.</p>
<p>There are now far too many devices, with a huge variety of sizes, to make that feasible. This means that instead of targetting specific sizes for all designs, a better approach is to change the design at the size where the content starts to break in some way. Perhaps the line lengths become far too long, or a boxed out sidebar gets squashed and hard to read. That's the point at which you want to use a media query to change the design to a better one for the space you have available. This approach means that it doesn't matter what the exact dimensions are of the device being used, every range is catered for. The points at which a media query is introduced are known as <strong>breakpoints</strong>.</p>
<p>The <a href="/en-US/docs/Tools/Responsive_Design_Mode">Responsive Design Mode</a> in Firefox DevTools is very useful for working out where these breakpoints should go. You can easily make the viewport smaller and larger to see where the content would be improved by adding a media query and tweaking the design.</p>
<p><img alt="A screenshot of a layout in a mobile view in Firefox DevTools." src="https://mdn.mozillademos.org/files/16867/rwd-mode.png" style="height: 917px; width: 1443px;"></p>
<h2 id="Active_learning_mobile_first_responsive_design">Active learning: mobile first responsive design</h2>
<p>Broadly, you can take two approaches to a responsive design. You can start with your desktop or widest view and then add breakpoints to move things around as the viewport becomes smaller, or you can start with the smallest view and add layout as the viewport becomes larger. This second approach is described as <strong>mobile first</strong> responsive design and is quite often the best approach to follow.</p>
<p>The view for the very smallest devices is quite often a simple single column of content, much as it appears in normal flow. This means that you probably don't need to do a lot of layout for small devices — order your source well and you will have a readable layout by default.</p>
<p>The below walkthrough takes you through this approach with a very simple layout. In a production site you are likely to have more things to adjust within your media queries, however the approach would be exactly the same.</p>
<h3 id="Walkthrough_a_simple_mobile-first_layout">Walkthrough: a simple mobile-first layout</h3>
<p>Our starting point is an HTML document with some CSS applied to add background colors to the various parts of the layout.</p>
<pre class="brush: css"><code>* {
box-sizing: border-box;
}
body {
width: 90%;
margin: 2em auto;
font: 1em/1.3 Arial, Helvetica, sans-serif;
}
a:link,
a:visited {
color: #333;
}
nav ul,
aside ul {
list-style: none;
padding: 0;
}
nav a:link,
nav a:visited {
background-color: rgba(207, 232, 220, 0.2);
border: 2px solid rgb(79, 185, 227);
text-decoration: none;
display: block;
padding: 10px;
color: #333;
font-weight: bold;
}
nav a:hover {
background-color: rgba(207, 232, 220, 0.7);
}
.related {
background-color: rgba(79, 185, 227, 0.3);
border: 1px solid rgb(79, 185, 227);
padding: 10px;
}
.sidebar {
background-color: rgba(207, 232, 220, 0.5);
padding: 10px;
}
article {
margin-bottom: 1em;
}
</code></pre>
<p>We've made no layout changes, however the source of the document is ordered in a way that makes the content readable. This is an important first step and one which ensures that if the content were to be read out by a screen reader, it would be understandable.</p>
<pre class="brush: html"><code><body>
<div class="wrapper">
<header>
<nav>
<ul>
<li><a href="">About</a></li>
<li><a href="">Contact</a></li>
<li><a href="">Meet the team</a></li>
<li><a href="">Blog</a></li>
</ul>
</nav>
</header>
<main>
<article>
<div class="content">
<h1>Veggies!</h1>
<p>
...
</p>
</div>
<aside class="related">
<p>
...
</p>
</aside>
</article>
<aside class="sidebar">
<h2>External vegetable-based links</h2>
<ul>
<li>
...
</li>
</ul>
</aside>
</main>
<footer><p>&copy;2019</p></footer>
</div>
</body>
</code></pre>
<p>This simple layout also works well on mobile. If we view the layout in Responsive Design Mode in DevTools we can see that it works pretty well as a straightforward mobile view of the site.</p>
<p><a href="https://mdn.github.io/css-examples/learn/media-queries/step1.html">Open step 1</a> in the browser, or <a href="https://github.com/mdn/css-examples/blob/master/learn/media-queries/step1.html">view the source</a>.</p>
<p><strong>If you want to follow on and implement this example as we go, make a local copy of <a href="https://github.com/mdn/css-examples/blob/master/learn/media-queries/step1.html">step1.html</a> on your computer.</strong></p>
<p>From this point, start to drag the Responsive Design Mode view wider until you can see that the line lengths are becoming quite long, and we have space for the navigation to display in a horizontal line. This is where we'll add our first media query. We'll use ems, as this will mean that if the user has increased their text size, the breakpoint will happen at a similar line-length but wider viewport, than someone with a smaller text size.</p>
<p><strong>Add the below code into the bottom of your step1.html CSS.</strong></p>
<pre class="brush: css"><code>@media screen and (min-width: 40em) {
article {
display: grid;
grid-template-columns: 3fr 1fr;
column-gap: 20px;
}
nav ul {
display: flex;
}
nav li {
flex: 1;
}
}
</code></pre>
<p>This CSS gives us a two-column layout inside the article, of the article content and related information in the aside element. We have also used flexbox to put the navigation into a row.</p>
<p><a href="https://mdn.github.io/css-examples/learn/media-queries/step2.html">Open step 2</a> in the browser, or <a href="https://github.com/mdn/css-examples/blob/master/learn/media-queries/step2.html">view the source</a>.</p>
<p>Lets continue to expand the width until we feel there is enough room for the sidebar to also form a new column. Inside a media query we'll make the main element into a two column grid. We then need to remove the {{cssxref("margin-bottom")}} on the article in order that the two sidebars align with each other, and we'll add a {{cssxref("border")}} to the top of the footer. Typically these small tweaks are the kind of thing you will do to make the design look good at each breakpoint.</p>
<p><strong>Again, add the below code into the bottom of your step1.html CSS.</strong></p>
<pre class="brush: css"><code>@media screen and (min-width: 70em) {
main {
display: grid;
grid-template-columns: 3fr 1fr;
column-gap: 20px;
}
article {
margin-bottom: 0;
}
footer {
border-top: 1px solid #ccc;
margin-top: 2em;
}
}</code>
</pre>
<p><a href="https://mdn.github.io/css-examples/learn/media-queries/step3.html">Open step 3</a> in the browser, or <a href="https://github.com/mdn/css-examples/blob/master/learn/media-queries/step3.html">view the source</a>.</p>
<p>If you look at the final example at different widths you can see how the design responds and works as a single column, two columns, or three columns, depending on the available width. This is a very simple example of a mobile first responsive design.</p>
<h2 id="Do_you_really_need_a_media_query">Do you really need a media query?</h2>
<p>Flexbox, Grid, and multi-column layout all give you ways to create flexible and even responsive components without the need for a media query. It's always worth considering whether these layout methods can achieve what you want without adding media queries. For example, you might want a set of cards that are at least 200 pixels wide, with as many of these 200 pixels as will fit into the main article. This can be achieved with grid layout, using no media queries at all.</p>
<p>This could be achieved using the following:</p>
<pre class="brush: html"><code><ul class="grid">
<li>
<h2>Card 1</h2>
<p>...</p>
</li>
<li>
<h2>Card 2</h2>
<p>...</p>
</li>
<li>
<h2>Card 3</h2>
<p>...</p>
</li>
<li>
<h2>Card 4</h2>
<p>...</p>
</li>
<li>
<h2>Card 5</h2>
<p>...</p>
</li>
</ul></code></pre>
<pre class="brush: css"><code>.grid {
list-style: none;
margin: 0;
padding: 0;
display: grid;
gap: 20px;
grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
}
.grid li {
border: 1px solid #666;
padding: 10px;
}</code></pre>
<p><a href="https://mdn.github.io/css-examples/learn/media-queries/grid.html">Open the grid layout example</a> in the browser, or <a href="https://github.com/mdn/css-examples/blob/master/learn/media-queries/grid.html">view the source</a>.</p>
<p>With the example open in your browser, make the screen wider and narrower to see the number of column tracks change. The nice thing about this method is that grid is not looking at the viewport width, but the width it has available for this component. It might seem strange to wrap up a section about media queries with a suggestion that you might not need one at all! However, in practice you will find that good use of modern layout methods, enhanced with media queries, will give the best results.</p>
<h2 id="Test_your_skills!">Test your skills!</h2>
<p>You've reached the end of this article, but can you remember the most important information? You can find a test to verify that you've retained this information before you move on — see <a href="/en-US/docs/Learn/CSS/CSS_layout/rwd_skills">Test your skills: Responsive Web Design</a>.</p>
<h2 id="Summary">Summary</h2>
<p>In this lesson you have learned about media queries, and also discovered how to use them in practice to create a mobile first responsive design.</p>
<p>You could use the starting point that we have created to test out more media queries. For example, perhaps you could change the size of the navigation if you detect that the visitor has a coarse pointer, using the <code>pointer</code> media feature.</p>
<p>You could also experiment with adding different components and seeing whether the addition of a media query, or using a layout method like flexbox or grid is the most appropriate way to make the components responsive. Very often there is no right or wrong way — you should experiment and see which works best for your design and content.</p>
<p>{{PreviousMenuNext("Learn/CSS/CSS_layout/Responsive_Design", "Learn/CSS/CSS_layout/Legacy_Layout_Methods", "Learn/CSS/CSS_layout")}}</p>
<h2 id="In_this_module">In this module</h2>
<ul>
<li><a href="/en-US/docs/Learn/CSS/CSS_layout/Introduction">Introduction to CSS layout</a></li>
<li><a href="/en-US/docs/Learn/CSS/CSS_layout/Normal_Flow">Normal flow</a></li>
<li><a href="/en-US/docs/Learn/CSS/CSS_layout/Flexbox">Flexbox</a></li>
<li><a href="/en-US/docs/Learn/CSS/CSS_layout/Grids">Grid</a></li>
<li><a href="/en-US/docs/Learn/CSS/CSS_layout/Floats">Floats</a></li>
<li><a href="/en-US/docs/Learn/CSS/CSS_layout/Positioning">Positioning</a></li>
<li><a href="/en-US/docs/Learn/CSS/CSS_layout/Multiple-column_Layout">Multiple-column layout</a></li>
<li><a href="/en-US/docs/Learn/CSS/CSS_layout/Responsive_Design">Responsive design</a></li>
<li><a href="/en-US/docs/Learn/CSS/CSS_layout/Media_queries">Beginner's guide to media queries</a></li>
<li><a href="/en-US/docs/Learn/CSS/CSS_layout/Legacy_Layout_Methods">Legacy layout methods</a></li>
<li><a href="/en-US/docs/Learn/CSS/CSS_layout/Supporting_Older_Browsers">Supporting older browsers</a></li>
<li><a href="/en-US/docs/Learn/CSS/CSS_layout/Fundamental_Layout_Comprehension">Fundamental layout comprehension assessment</a></li>
</ul>
|