Making Web Pages Responsive With CSS Media Queries

This tutorial is part of a web programming course for people who have no programming experience.


You've already learned that setting the width of an element to a percent can allow the element to stretch or shrink depending on the screen size used to visit a web page. When a web page adapts itself to various screen sizes, it is said to be responsive. Nowadays all of your web pages should be responsive because there are so many devices that can be used to visit your site. Mobile phones have small screens, tablets can be held in 'landscape' or 'portrait' orientation, and of course there are monitors that can range in size. One of the big challenges to web developers is to creating web pages that look good on any device.

In this lesson we'll discuss CSS media queries, which allow your page to detect the screen size of a device, and apply different rulesets for various sizes. We'll also talk about a simple technique for making your images responsive.

We'll use this HTML as our starter code:

<!DOCTYPE html>
<html>
    <head>
        <title>SAMPLE CODE - Responsive CSS</title>
        <style type="text/css">
        	html,h1,header{margin:0; padding:0; } 
        	body{ height:2500px; }
           
            /* ADD ALL CSS SAMPLE CODE HERE */
        
        </style>
    </head>
    <body>
        <header>
            <h1>Responsive CSS</h1>
        </header>
        <div id="content" class="clearfix">
            <main>
                <h2>This is the main content area</h2>
          		<!-- ADD ALL HTML SAMPLE CODE HERE --> 
            </main>
            <aside>
                <h2>This is the side bar</h2>
            </aside>
        </div>
    </body>
</html>

Note that you normally wouldn't need to set the height on the body element. I just did it because our page will not have much content and I wanted to force it to be tall so that the scroll bar appears on the right.

Here is the starter CSS code, it should be familiar because we used it in previous lessons. Go ahead and copy it into the STYLE element and then spend a minute or two inspecting it.

header{
    position: fixed;
    height: 100px;
    width: 100%;
    top: 0px;
    left: 0px;
    z-index: 2;
    background-color:darkgray;
    color:white;
}

header h1{
    font-size: 72px;
}

#content{
    position: relative;
    top:100px;
}

.clearfix::after{
    content: "";
    display: table;
    clear: both;
}

main{
    float: left;
    width: 70%;
    box-sizing: border-box;
    padding:20px;
}

aside{
    float: left;
    width: 30%;
    box-sizing: border-box;
    padding:20px;
}

CSS Media Queries

As mentioned, one of the challenges for web developers over the last few years is making a web page look great on all devices. On a large screen, there is enough space for a page that has two or three columns. But it doesn't make sense to try and squeeze two columns into a small screen.

Luckily, there is a way to make your web page adapt to the screen size by using CSS media queries. A media query is a different set of CSS rules that will be automatically applied by the browser depending on the screen size of the device.

To add a media query to your CSS code, you can start by doing this:

@media all and (max-width : 600px) {

    /* rulesets go here */
    
}

As usual, the syntax is a little strange (maybe it's just me!). The first line tells the browser that the rulesets should be applied to all media devices that are 600 pixels wide or less. If the browser meets this condition, then the rulesets in between the curly braces will be applied, and they will override any conflicting rules that are not in the media query. There are various different ways that you can set up these conditions, but we won't go too deeply into them.

In this example we used 600 pixels as the point at which our layout changes. This is known as the break point. You can set this to another value if you like. You can also add multiple media queries in an effort to accomodate as many screen sizes as possible. But we won't get into those details now.

When creating a web page, I often design for a two column layout and then add a media query for smaller screens to force the page back to use a one column layout. In a previous step we set the float property to 'left' for the MAIN and ASIDE elements. This made the elements sit side by side, giving us a two-column layout. Since we don't have room for a two-column layout on small screens, we'll remove the float in the media query, by setting the float property to 'none'. We also set the widths of the MAIN and ASIDE elements to 70% and 30% respectively. Inside the media query, we can reverse these effects. Add this ruleset inside the curly braces of the media query, and make sure to indent it. Your entire media query should now look like this:

@media all and (max-width : 600px) {
    main, aside{
        float: none;
        width: 100%
    }
}

If you resize the width of the browser window, you should see the media query kick in when the window width becomes less than 600px.

Another change that you may want to make for small screens is to reduce the height of the header. If the header is tall, then it can occupy too much vertical space on a small screen. The next sample alters the height of the header (reduces it from 100px which was set before the media query to 50px). We'll also need to change the position of the #content DIV so that it is 50px from the top rather than 100. Be sure to place this code inside the media query (and indent it).

header{ height: 50px; }

#content{ top: 50px; }

Now, if you resize the browser window, you'll see that the HEADER element adjusts it height when you hit the breakpoint. But now we have another problem, the font in the H1 element is too big for the HEADER. Let's fix that by adding this ruleset inside the media query:

header h1{ font-size: 40px; }

There are other issues that you'll encounter when you look at your web pages at various screen sizes, but these are some of the most common.

The Meta Viewport Element

When using media queries to control the layout of your pages for various devices, you should add a certain META element (this element should be placed inside the HEAD element):

<meta name="viewport" content="width=device-width">

By default, browsers will try to scale a web page to fit inside the screen of a mobile device. But by using media queries to adapt to various screen sizes, we don't want the browser to shrink the page down (because the media query takes care of adapting the page for small screens). So the meta/viewport element, with the CONTENT attribute set to a value of 'width=device-width' tells the browser not to scale the page.

Responsive Images

Managing images for a website has become quite complicated because of all the devices that can be used to surf the net. Because of this, many website now use multiple copies of images, at various sizes and resolutions. So if a visiter used a phone to visit the site, one version of an image will be displayed. If another visitor uses a large monitor, then a different (bigger) version of the image can be displayed. This can get to be quite messy and we won't get into it in this course, but there is something that we can do now to help our images adapt to different screen sizes.

Images can have a percent value set for their width property to make them responsive (some programmers call them 'fluid' images). This means they will stretch or shrink depending on the screen size of the device being used to view the page. If you set the width to 100% the image will stretch out across the entire width of its parent element. You may not want the image to strecth across an entire screen, or column, so you can constrain it's width by nesting it inside another element. Add this HTML code inside the MAIN element (I've incuded a paragraph of jibberish content to provide some context around the image):

<div class="img-container">
    <img src="../images/Desert.jpg" alt="A desert">
</div>
<p>
    Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod
    tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,
    quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
    consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse
    cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non
    proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
</p>

Now add this CSS code to the STYLE element, note that this code does not belong inside the media query, I suggest you place it just before it.

.img-container{
    width:50%;
    float: left;
    padding:0 12px 12px 0; 
}

.img-container img{
    width: 100%;
}

To control the width of the picture, you can change the percent width of the container. Make sure to leave the image itself at 100%.

Finally, lets add this code inside the media query to prevent the image from shrinking too much on small screens:

.img-container{
    width:100%;
    float: none;
    padding:0px; 
}

I must point out that this is not an optimal approach to including responsive images in your web pages. The problem is that in order for this to work, you'll want your images to be fairly large (for big screens). Larger image have larger files sizes (in KB) and therefore take longer to load. For smaller screens, you are still using the same large image, but it's being squeezed by you CSS code. It's not optimal to load a large image, only to shrink it in the browser window. Ideally, you'd want various versions of each image that you put on your website; a large version for large screens, and various smaller versions for smaller screens. As I mentioned, this gets a little messy and is beyond the scope of this course. But if you are curious, you can look up 'img srcset' for more information.

NEXT LESSON: CSS Layout