Jared Youtsey | ng-conf | Jul 2020
This is not intended to be a deep dive into media queries, but a primer to help understand some common way we use media queries as web-developers.
A media query is a bit of CSS that defines rules about when to apply a set of CSS definitions. It always starts with
@media
As web-devs we’re most concerned with the screen as our rendered output, so, almost always, we follow the @media
with
screen
screen
means that it applies to screen-based device like a phone, tablet, or computer screen. There are other options, but they are less-frequently used.
We would then usually append a query to the statement, so, we’ll end up with something like:
@media screen and ...
Queries, like all css, are applied in the order they are defined.
This is very important to understand, as we usually want to be doing “Mobile-First” development.
What is Mobile-First?
Mobile-First means that we define the layout rules in CSS for the smallest form-factor first (a phone in portrait mode). Then, we define queries to target devices as they get incrementally larger. We usually will have some SASS variables that map roughly to common device sizes.
Why don’t we have variables for specific devices? The rules would become impossible to write and maintain. Device resolution changes drastically from one phone to another.
Two very common queries we are likely to use are min-width
and max-width
.
Meaning of min-width and max-width
=" under Meaning, and "Do not use with $*-max-width variables!" under Notes. The second row reads "max-width" under Rule, "less than or equal to <=" under Meaning, and "Do not use with $*-min-width variables!" under Notes."/>
SASS variables and queries to target ranges of devices.
Media queries can be combined with and
. For example, the following query will target only landscape phones (give or take a randomly sized phone/tablet).
@media screen and (min-width: $sm-min-width) and (max-width: $sm-max-width)
Demo
Here is a simple example where we will adapt the presentation of some buttons based on the size of the device they are rendered on.
<html>
<!--
Phone Tablet Desktop
Variable em px Query Port Land Port Land
------------------------------------------------------------------------------------------------------------------
By default you should not write any media query at all. So, the first X X | X X | X
CSS definitions in your CSS file will apply to all devices unless you | |
have additional media queries defined afterward. | |
------------------------------------------------------------------------------------------------------------------
$sm-min-width 35.5em 568px min-width: 35.5em X | X X | X
------------------------------------------------------------------------------------------------------------------
$sm-max-width 47.999em 767.984px max-width: 47.999em X X | |
------------------------------------------------------------------------------------------------------------------
$md-min-width 48em 768px min-width: 48em | X X | X
------------------------------------------------------------------------------------------------------------------
$md-max-width 63.999em 1023.984px max-width: 63.999em X X | X |
------------------------------------------------------------------------------------------------------------------
$lg-min-width 64em 1024px min-width: 64em | X | X
------------------------------------------------------------------------------------------------------------------
$lg-max-width 79.999em 1279.984px max-width: 79.999em X X | X X |
------------------------------------------------------------------------------------------------------------------
$xl-min-width 80em 1280px min-width: 80em | X | X
------------------------------------------------------------------------------------------------------------------
* CSS vars cannot be used in media queries. SASS variables do since they get compiled to concrete values.
* There is some overlap at Phone/Tablet/Desktop boundaries due to the variances in device resolutions.
* When using CSS do not use min/max-width, rather use min/max-device-width to account for varying scale factors.
* Most SASS pre-processors will make min/max-width work correctly for the scale factor on the device (not sure how?!).
Rule Meaning Notes
min-width greater than or equal to >= Do not use with $*-max-width variables!
max-width less than or equal to <= Do not use with $*-min-width variables!
* Save this HTML/CSS as media-queries.html and open it in Chrome.
* Open Chrome Developer Tools
* Click the Responsive button
* Choose iPhone 6/7/8
* Notice that the buttons are stacked, fab buttons and it is labeled as Phone Portrait.
* Toggle to landscape rotation
* Notice that the buttons are flexed to either end of the screen and it’s labeled Phone Landscape.
* Choose iPad
* Notice that the buttons are flexed to either end of the screen and now use text labels and it’s labeled Tablet Portrait.
* Toggle to landscape rotation
* Notice that the buttons are flexed to either end of the screen and use both fab icons and text labels and it’s labeled Tablet Landscape/Desktop.
What’s really going on under the covers?
* Lines 76-126 define the default styling, which we have dictated will be mobile-first.
So these are the default styles for a phone in portrait mode.
* Lines 131-145 define styling for anything at least as large as a phone in landscape mode.
The only styles defined in this block are those that override what is defined in the
mobile-first, portrait phone section. So, we would expect at all form factors above
portrait phone that the buttons would be in a row, rather than a column.
* Lines 150-163 define styling for anything at least as large as a tablet in portrait mode.
Again, we only override styles that need to change. We hide the icon and now show text
on the button. We also go to a rounded corner button rather than a fab button. There is
no picture for this one because subsequent queries inherit from this one and then set
additional styling. There is no view where this query applies and other that build on it do not.
* Lines 170-184 define styling for ONLY a tablet in portrait mode.
This block inherits from previous queries, i.e. showing text instead of the icon. But it
overrides the borders and radius of the button to be much more round and pronounced.
Subsequent queries will not inherit from this one because this one has both a min and max query.
* Lines 190-204 define styling for anything tablet in landscape or larger.
It inherits from all previous queries except block 170-184, which is scoped with a min + max query.
It will show both the icon and the text.
* What kind of borders will the buttons have?
* What kind of layout will the buttons have?
-->
<head>
<style>
/*
* MOBILE FIRST!
* Which technically is the same as this media query:
* @media screen and (min-width: 0em)
* Which means "greater than or equal to 0em wide", or, "everything".
*/
body {
padding: 16px;
}
.button-container {
display: flex;
flex-direction: column;
align-items: center;
}
.add-button,
.delete-button {
border-radius: 50%;
width: 64px;
height: 64px;
font-size: 48px;
color: white;
margin-bottom: 16px;
}
.add-button {
border: solid 1px darkgreen;
background-color: forestgreen;
}
.delete-button {
border: solid 1px maroon;
background-color: red;
}
span.text {
display: none;
margin: 0 16px;
}
span.fab {
display: inline-block;
position: relative;
top: -5px;
}
.phone-portrait,
.phone-landscape,
.tablet-portrait,
.tablet-landscape {
display: flex;
justify-content: center;
font-weight: bold;
font-size: 24px;
}
.phone-portrait {
font-size: 48px;
}
.phone-landscape,
.tablet-portrait,
.tablet-landscape {
display: none;
}
/*
* Phone Landscape or larger
*/
@media screen and (min-device-width: 35.5em) {
/* These settings add to or override those that come before */
.button-container {
flex-direction: row;
justify-content: space-between;
}
.phone-landscape {
display: flex;
}
.phone-portrait,
.tablet-portrait,
.tablet-landscape {
display: none;
}
}
/*
* Tablet Portrait or larger
*/
@media screen and (min-device-width: 48em) {
.add-button,
.delete-button {
border-radius: 6px;
width: unset;
height: unset;
}
span.fab {
display: none;
}
span.text {
display: inline-block;
}
}
/*
* Tablet Portrait ONLY
* Inherits from previous queries.
* Subsequent queries will not inherit these values.
*/
@media screen and (min-device-width: 48em) and (max-device-width: 63.999em) {
.add-button,
.delete-button {
border-radius: 32px;
border-width: 4px;
}
.tablet-portrait {
display: flex;
}
.phone-portrait,
.phone-landscape,
.tablet-landscape {
display: none;
}
}
/*
* Tablet Landscape or larger
* Display both text and icon.
*/
@media screen and (min-device-width: 64em) {
span.fab {
display: inline-block;
margin-left: 16px;
top: -3px;
}
.tablet-landscape {
display: flex;
}
.phone-portrait,
.phone-landscape,
.tablet-portrait {
display: none;
}
}
</style>
</head>
<body>
<div class="button-container">
<button class="add-button">
<span class="fab">+</span>
<span class="text">Add</span>
</button>
<button class="delete-button">
<span class="fab">x</span>
<span class="text">Delete</span>
</button>
</div>
<div class="phone-portrait">Phone Portrait</div>
<div class="phone-landscape">Phone Landscape</div>
<div class="tablet-portrait">Tablet Portrait</div>
<div class="tablet-landscape">Tablet Landscape/Desktop</div>
</body>
</html>
css-media-queries.html hosted by GitHub
For the purposes of this example, we are using min/max-device-width
instead of min/max-width
since the example is in plain HTML/CSS.
If you are using Angular you can use min/max-width
. I’m not sure what the SASS compilation process is doing or setting to make that work. Just know that where you see min/max-device-width
in the sample HTML you can use min/max-width
in Angular with compiled SASS. This may or may not be true with plain CSS in Angular, or other SASS compilers?
- Save this HTML/CSS as media-queries.html and open it in Chrome.
- Open Chrome Developer Tools
- Click the Responsive button
- Choose iPhone 6/7/8
- Notice that the buttons are stacked fab buttons and it is labeled as Phone Portrait.
- Toggle to landscape rotation
- Notice that the buttons are flexed to either end of the screen and it’s labeled Phone Landscape.
- Chose iPad
- Notice that the buttons are flexed to either end of the screen and now use text labels and it is labeled Tablet Portrait.
- Toggle to landscape rotation
- Notice that the buttons are flexed to either end of the screen and use both fab icons and text labels and it is labeled Tablet Landscape/Desktop.
What’s really going on under the covers?
- Lines 76–126 define the default styling, which we have dictated will be mobile-first. So these are the default styles for a phone in portrait mode.
Lines 76–126 Phone Portrait
Lines 131–145 define styling for anything at least as large as a phone in landscape mode. The only styles defined in this block are those that override what is defined in the mobile-first, portrait phone section. So, we would expect at all form factors above portrait phone that the buttons would be in a row, rather than a column.
Lines 131–145 Phone Landscape
Lines 150–163 define styling for anything at least as large as a tablet in portrait mode. Again, we only override styles that need to change. We hide the icon and now show text on the button. We also go to a rounded corner button rather than a fab button. There is no picture for this one because subsequent queries inherit from this one and then set additional styling. There is no view where this query applies and other that build on it do not.
Lines 170–184 define styling for ONLY a tablet in portrait mode. This block inherits from previous queries, i.e. showing text instead of the icon. But it overrides the borders and radius of the button to be much more round and pronounced. Subsequent queries will not inherit from this one because this one has both a min and max query.
Lines 150–184 Tablet Portrait
Lines 190–204 define styling for anything tablet in landscape or larger. It inherits from all previous queries except block 170–184, which is scoped with a min + max query. It will show both the icon and the text.
Test yourself!
- What kind of borders will the buttons have?
- What kind of layout will the buttons have?
As you can see media queries provide us with great power to adapt our presentation incrementally for effective mobile-first presentation. Of course media queries can be used to adapt presentation for other uses, such as print or even screen readers.
Image by Photoshot from Pixabay
*ng-conf: Join us for Reliable Web Summit *
Come learn from community members and leaders the best ways to build reliable web applications, write quality code, choose scalable architectures, and create effective automated tests. Powered by ng-conf, join us for the Reliable Web Summit this August 26th & 27th, 2021.
https://reliablewebsummit.com/
Top comments (0)