One popular technique with using media queries is called mobile first. The mobile first approach includes using styles targeted at smaller viewports as the default styles for a website, then use media queries to add styles as the viewport grows.
The operating belief behind mobile first design is that a user on a mobile device, commonly using a smaller viewport, should’t have to load the styles for a desktop computer only to have them over written with mobile styles later. Doing so is a waste of bandwidth. Bandwidth that is precious to any users looking for a snappy website.
The mobile first approach also advocates designing with the constraints of a mobile user in mind. Before too long, the majority of Internet consumption will be done on a mobile device. Plan for them accordingly and develop intrinsic mobile experiences.
A breakout of mobile first media queries might look at bit like the following.
/* Default styles first then media queries */
@media screen and (min-width: 400px) {...}
@media screen and (min-width: 600px) {...}
@media screen and (min-width: 1000px) {...}
@media screen and (min-width: 1400px) {...}
Additionally, downloading unnecessary media assets can be stopped by using media queries. Generally speaking, avoiding CSS3 shadows, gradients, transforms, and animations within mobile styles isn’t a bad idea either. When used excessively, they cause heavy loading and can even reduce a device’s battery life.
/* Default media */
body {
background: #ddd;
}
/* Media for larger devices */
@media screen and (min-width: 800px) {
body {
background-image: url("bg.png") 50% 50% no-repeat;
}
}
Mobile First Demo
Adding media queries to our previous example, we overwrote a handful of styles in order to have a better layout on viewports under
420
pixels wide. Rewriting this code to use the mobile styles first by default then adding media queries to adjust for viewports over 420
pixels wide we build the following:
section, aside {
margin: 1.51515151%;
}
@media all and (min-width: 420px) {
.container {
max-width: 660px;
}
section {
float: left;
width: 63.63636363%;
}
aside {
float: right;
width: 30.30303030%;
}
}
Notice, this is the same amount of code as before. The only exception here is that mobile devices only have to render only one CSS declaration. All of the other styles are deferred, only loading on larger viewports and done so without overwriting any initial styles.
Viewport
Mobile devices generally do a pretty decent job of displaying websites these days. Sometimes they could use a little assistance though, particularly around identifying the viewport size, scale, and resolution of a website. To remedy this, Apple invented the
viewport
meta tag.Viewport Height & Width
Using the
viewport
meta tag with either the height
or width
values will define the height or width of the viewport respectively. Each value accepts either a positive integer or keyword. For the height
property the keyword device-height
value is accepted, and for the width
property the keyword device-width
is accepted. Using these keywords will inherit the device’s default height and width value.
For the best results, and the best looking website, it is recommend that you use the device defaults by applying the
device-height
and device-width
values.
- HEIGHT & WIDTH
<meta name="viewport" content="width=device-width">
Viewport Scale
To control how a website is scaled on a mobile device, and how users can continue to scale a website, use the
minimum-scale
, maximum-scale
, initial-scale
, and user-scalable
properties.
The
initial-scale
of a website should be set to 1
as this defines the ratio between the device height, while in a portrait orientation, and the viewport size. Should a device be in landscape mode this would be the ratio between the device width and the viewport size. Values for initial-scale
should always be a positive integer between 0
and 10
.
<meta name="viewport" content="initial-scale=2">
The
minimum-scale
and maximum-scale
values determine how small and how large a viewport may be scaled. When using minimum-scale
the value should be a positive integer lower than or equal to the initial-scale
. Using the same reasoning, the maximum-scale
value should be a positive integer greater than or equal to the initial-scale
. Values for both of these must also be between 0
and 10
.
- MINIMUM & MAXIMUM SCALE
<meta name="viewport" content="minimum-scale=0">
Generally speaking, these values should not be set to the same value as the
initial-scale
. This would disable any zooming, which can be accomplished instead by using the user-scalable
value. Setting the user-scalable
value to no
will disable any zooming. Alternatively, setting the user-scalable
value to yes
will turn on zooming.
Turning off the ability to scale a website is a bad idea. It harms accessibility and usability, preventing those with disabilities from viewing a website as desired.
<meta name="viewport" content="user-scalable=yes">
Viewport Resolution
Letting the browser decide how to scale a website based off any viewport scale values usually does the trick. When more control is needed, specifically over the resolution of a device, the
target-densitydpi
value may be used. Thetarget-densitydpi
viewport accepts a handful of values including device-dpi
, high-dpi
, medium-dpi
, low-dpi
, or an actual DPI number.
Using the
target-densitydpi
viewport value is rare, but extremely helpful when pixel by pixel control is needed.
<meta name="viewport" content="target-densitydpi=device-dpi">
Combining Viewport Values
The
viewport
meta tag will accept individual values as well as multiple values, allowing multiple viewport properties to be set at once. Setting multiple values requires comma separating them within the content
attribute value. One of the recommended viewport values is outlined below, using both the width
and initial-scale
properties.
<meta name="viewport" content="width=device-width, initial-scale=1">
CSS Viewport Rule
Since the
viewport
meta tag revolves so heavily around setting the styles of how a website should be rendered it has been recommend to move the viewport from a meta tag with HTML to an @
rule within CSS. This helps keep the style separated from content, providing a more semantic approach.
Currently some browsers have already implemented the
@viewport
rule, however support isn’t great across the board. The previously recommended viewport
meta tag would look like the following @viewport
rule in CSS.
@viewport {
width: device-width;
zoom: 1;
}
Flexible Media
The final, equally important aspect to responsive web design involves flexible media. As viewports begin to change size media doesn’t always follow suit. Images, videos, and other media types need to be scalable, changing their size as the size of the viewport changes.
One quick way to make media scalable is by using the
max-width
property with a value of 100%
. Doing so ensures that as the viewport gets smaller any media will scale down according to its containers width.
img, video, canvas {
max-width: 100%;
}
Flexible Media Demo
100% WIDE CONTAINER
75% WIDE CONTAINER
50% WIDE CONTAINER
Flexible Embedded Media
Unfortunately the
max-width
property doesn’t work well for all instances of media, specifically around iframes
and embedded media. When it comes to third party websites, such as YouTube, who use iframes for embedded media this is a huge disappointment. Fortunately, there is a work around.
To get embedded media to be fully responsive, the embedded element needs to be absolutely positioned within a parent element. The parent element needs to have a
width
of 100%
so that it may scale based on the width of the viewport. The parent element also needs to have a height
of 0
to trigger the hasLayout
mechanism within Internet Explorer.
Padding is then given to the bottom of the parent element, the value of which is set in the same aspect ratio of the video. This allows the height of the parent element to be proportionate to that of it’s width. Remember the responsive design formula from before? If a video has an aspect ratio of 16:9,
9
divided by 16
equals .5625
, thus requiring a bottom padding of 56.25%
. Padding on the bottom and not the top is specifically used to prevent Internet Explorer 5.5 from breaking, and treating the parent element as an absolutely positioned element.HTML
<figure>
<iframe src="https://www.youtube.com/embed/4Fqg43ozz7A"></iframe>
</figure>
CSS
figure {
height: 0;
padding-bottom: 56.25%; /* 16:9 */
position: relative;
width: 100%;
}
iframe {
height: 100%;
left: 0;
position: absolute;
top: 0;
width: 100%;
}