Categories
Articles Tutorial

Mobile First Responsive Design Layout and Flexible Image Tutorial


Previous | Part 5 of 5
By Lon Hosford

Time to put CSS responsive design into action with example that can serve as basic template. This is the last of five articles on Mobile First Responsive Design.

Mobile First Responsive Design Layout and Flexible Image Tutorial
Mobile First Responsive Design Layout and Flexible Image Tutorial
The previous articles introduced using the link element to select external CSS files based on screen widths. The technique detects the minimum width breakpoint for a range of screen widths with the breakpoint being the smallest width.

This technique provides an opportunity to add CSS @media selectors into each of these external CSS files in a way that mimics CSS media query nesting. Nesting CSS media queries is introduced with CSS3, but reports as of this article is that they are not reliable across CSS3 compatible web browsers.

Additionally the use of the external CSS files for each screen width breakpoint helps organize and plan the climb from the smallest width to the largest width. As we move forward we can make adjustment for special needs. For example an intermediate width need can be handled with an @media selector in one of the minimum width CSS files. Or another example is the landscape orientation. This is what we do in this example.

[ad name=”Google Adsense”]

Here is the step by step video. You can follow along or audit. It will reveal the decision making process and show the progressive changes as the choices are applied. This way you can make visual comparisons.

[iframe https://www.youtube.com/embed/CRSxF7a95Go 640 360]
[ad name=”Pearson Web Dev Books”]
Source Files for the video series: Download

In this post the completed code is presented along with comments on the relevant items.

HTML Overview – practice.html File

These are the link elements for each separate CSS file.

  • base.css for basic styling of all the structure elements.
  • screen-min-320.css for smartphones widths through tablet widths.
  • screen-min-768.css for tablet widths through laptop desktop widths.
  • screen-min-1024.css for laptop desktop widths.

The media attribute’s contains the media query rule. And as you see the are ordered mobile first which means base and then the smallest screen to the largest screen width breakpoint.

<title>CSS Mobile Media Queries 101 | Lon Hosford</title>;
<!-- Base css -->;
<link rel="stylesheet" type="text/css"href="base.css" />;
<!-- True if greater than or equal to 320px -->
<link rel="stylesheet" type="text/css" media="only screen and (min-width: 320px)" href="screen-min-320.css" />;
<!-- True if greater than or equal to 768px -->;
<link rel="stylesheet" type="text/css" media="only screen and (min-width: 768px)" href="screen-min-768.css" />;
<!-- True if greater than or equal to 1024px -->;
<link rel="stylesheet" type="text/css" media="only screen and (min-width: 1024px)" href="screen-min-1024.css" />;
</head>;

The content is structured with one container div element on lines 17 to 47.

There are four inner containers.

One for the page header one lines 18 to 20 containing one level one heading element.

One on lines 21 to 28 for the page content using the div id’d as main. It contains a single article. The article has a level 2 header and paragraph elements.

The third on lines 28 to 42 holds feature content in the div element id’d as featured. The featured content contains three articles. Each of those have a level 3 header element and a paragraph element.

And the last container is lines 43 to 45 for the page footer.

Line 46 is a Creative Commons link for the glyph icons used from GLYPHICONS.

Complete practice.html File

<!doctype html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewpor" content="width=device-width, initial-scale=1">
<title>CSS Mobile Media Queries 101 | Lon Gosford</title>
<!-- Base css -->
<link rel="stylesheet" type="text/css" href="base.css" />
<!-- True if greater than or equal to 320px -->
<link rel="stylesheet" type="text/css" media="only screen and (min-width: 320px)" href="screen-min-320.css" />
<!-- True if greater than or equal to 768px -->
<link rel="stylesheet" type="text/css" media="only screen and (min-width: 768px)" href="screen-min-768.css" />
<!-- True if greater than or equal to 1024px -->
<link rel="stylesheet" type="text/css" media="only screen and (min-width: 1024px)" href="screen-min-1024.css" />
</head>
<body>
<div id="container">
	<header>
		<h1>Scriptum Titulus</h1>
	</header>
	<div id="main">
		<article>
			<h2>Pagina Titulus</h2>
			<p><img src="user_female_400x400.png" alt="User female icon"/>Sed consequat feugiat dictum. Aliquam fermentum sodales lectus in aliquam. Duis venenatis augue quis eros egestas fringilla. In consectetur eleifend hendrerit. Praesent quis interdum ligula. Nulla et aliquam lorem, ut ultricies elit. Nulla blandit nunc orci, ac ultricies nisi ultricies sit amet. Suspendisse nec metus est. Donec sem diam, cursus nec enim et, interdum tristique quam. Aliquam et dolor arcu.</p>
			<p>Donec vel libero enim. In porta at mauris a mattis. Sed rhoncus dolor ut purus feugiat lobortis. Proin vel tellus consequat, mattis diam eu, egestas lacus. Morbi dictum justo ac erat condimentum venenatis. ctoginta et septem annos in hoc continente novam nationem pepererunt patrum in libertate conceptam, et dedicatam ad propositum quod omnes homines pares creantur.  Nulla accumsan in erat sit amet placerat. Nunc augue dolor, aliquet id ligula in, rhoncus sollicitudin elit. Phasellus rhoncus laoreet elit, ac aliquet risus tincidunt eu. Suspendisse vitae ligula commodo, tristique justo consectetur, congue justo. In semper sed quam eget rutrum. </p>
			<p>Eros fusce ut in dolor diam, nec aenean, adipiscing et delectus nibh. Fermentum maecenas aliquam malesuada at dolor ullamcorper, eu mattis sed et sociosqu morbi, metus hymenaeos cras lacus tincidunt, potenti vestibulum pede malesuada rutrum lorem. </p>	
		</article>
	</div>
	<div id="featured">
		<article>
			<h3>Sed eu dolor</h3>
			<p><img src="glyphicons_163_iphone_fff_stroke.png" width="24" height="24" alt="smart phone icon"/>Nulla accumsan in erat sit amet placerat. Maecenas ullamcorper id leo eu lacinia. In hac habitasse platea dictumst.</>;
		</article>		
		<article>
			<h3>Sed rhoncus dolor</h3>
			<p><img src="glyphicons_025_binoculars_fff_stroke.png" width="24" height="24" alt="binoculars icon"/>Octoginta et septem annos in hoc continente novam nationem pepererunt patrum in libertate conceptam, et dedicatam ad propositum quod omnes homines pares creantur. Bellum civile et magnum quidem iam nos occupans tentat rem publicam illam, vel sic nata et dedicata, diu manere potest. Nam occurrit illud magnum bellum bello.</p>
		</article>		
		<article>
			<h3>Phasellus rhoncus laoreet</h3>
			<p><img src="glyphicons_041_charts_fff_stroke.png" width="24" height="24" alt="bar chart icon"/>Bellum civile et magnum quidem iam nos occupans tentat rem publicam illam, vel sic nata et dedicata, diu manere potest. Proin vel tellus consequat, mattis diam eu, egestas lacus. Morbi dictum justo ac erat condimentum venenatis. Praesent quis interdum ligula. Nulla et aliquam lorem, ut ultricies elit.</p>
		</article>		
	</div>
	<footer>
		<p>Vestibulum MMXIV&</p>
	</footer>
	<small><a href="http://glyphicons.com/" target="_blank">GLYPHICONS</a> CC BY / Filter Effects</small>
</div>
</body>
</html>

The box-sizing CSS Property in Responsive Design

The base.css file uses border-box for the box-sizing property and applies it using the universal selector.

base.css

* {
	/* Use border box for width computation GE IE8 */
	-webkit-box-sizing:border-box;
	-moz-box-sizing:border-box;
	box-sizing:border-box;
	color:#fff;
	margin:0;
	padding:0;
}

The box-sizing property is all about what parts of the box model is included in the width property.

The default value content-box applies the width property to the content and not to the padding or border-width properties. As a result your box actual width appears larger than the width property setting when there is padding or border values.

The border-box value simply includes the border-width and padding in the border-width properties.

This becomes very helpful with percentage widths for flexible layouts and for flexible images.

Flexible Images

Flexible images are easy. I like to apply it as the default image styling. Then make adjustments as needed.

The need for the flexible images is the in between widths. We are only targeting minimum width breakpoints. Not all smart phones for example are 320 pixels wide. So this handles all the device widths up to the next width break point. For that matter it handles all device widths until we have a need to deviate.

base.css

/* Flexible images default */
img {height:auto; width: 100%; }

Flexible Images Override for Icons

Then we do have a need for images to remain at their defined size. So with a good HTML structure you should be able to target them. Here we have the images that are in the featured articles of the document. If there are other image needs within this target then we will need to be more specific.

Simple return the width and height properties back to the default value of auto.

We also have these icons float to the left so they appear at the start of the paragraphs containing them.

base.css

#featured article img{
	height:auto; width: auto;
	float:left;
    margin:0 1em 0 0;
}

Alternate Sizing for Flexible Images

Flexible images do not require 100% width. We can make adjustments for their width where it makes sense. Here we target the main article image to a 90% flexible width.

base.css

#main article img {
	background:rgba(0,0,0,.5);
	display:block;
	height:auto; 
    margin:1em auto 1em auto;
	padding:.2em;	
	width:90%;
}

Complete base.css File

/* Base CSS */
header, article{ display: block; } 
/* All elements */
* {
	/* Use border box for width computation GE IE8 */
	-webkit-box-sizing:border-box;
	-moz-box-sizing:border-box;
	box-sizing:border-box;
	color:#fff;
	margin:0;
	padding:0;
}
body { 
	background:#c9c9c9;
	font-family:Helvetica, Arial, sans-serif;
	font-size:.7em; 
	line-height:1.6; /* 1.6 x font-size */
}
/* Flexible images default */
img {height:auto; width: 100%; }
p { padding:0 0 1em 0; }
/* Page wrapper */
#container {
	color:#fff;
	padding:1em;
	background:rgba(189,76,31,.3);
}
header,
footer {
	margin:0 0 1em 0;
	padding:1em;
	background:rgba(0,0,0,.75);
}
#main article {
	background:rgba(0,0,0,.75);
	margin:0 0 1em 0;
	padding:1em;
}
#main article img {
	background:rgba(0,0,0,.5);
	display:block;
	height:auto; 
    margin:1em auto 1em auto;
	padding:.2em;	
	width:90%;
}
#featured article p{
	margin:0 0 1em 0;
	padding:1em;
	background:rgba(0,0,0,.75);
}
#featured article img{
	height:auto; width: auto;
	float:left;
    margin:0 1em 0 0;
}
footer {
	padding-bottom:0;
}

A Landscape Orientation Need Filled By The @media Selector

Keep in mind design drives the code. So we are simulating a design need for smartphone (320px – 1023px width) screens. That need is to have the main article image float to the right of the article text and have the text wrap it.

To solve that we added a CSS media query targeting landscape orientation in the screen-min-320.css file.

Because we used the link element to select this file, we have a simple CSS media query rule to write.

However is we did this say with one large CSS file we would have to have a compound media query rule that would include both the minimum width and orientation. Some like this only screen and (min-width: 320px) and (orientation:landscape).

You see you have alternatives and you just need to find the combination best suited to your needs. For beginners, separating out the target minimum widths using a mobile first design is my recommendation. Then use overrides like this to hone in on specific device detection needs.

Complete screen-min-320.css File

/* Smallest Screen Size Design Target */
/* Example: iPhone portrait */
/* True if width greater than or equal to 320px */
body {background:#FF0066;}
@media (orientation:landscape) {
	#main article img {
		float:right;
		display:inline;
		height:auto;
   		margin:0 1.1em .75em .75em;
		width:35%; 
	}
}

The One Column to Two Column Responsive Crossover

The widths from 768 pixels on up called for a two column layout moving the featured articles to the right of the main article.

So that is done with floated containers and using widths as percents. Since the box-sizing property is set to border-box we are more confident that the percentage widths will work and we will not have the push down problem where one floated container does not fit.

Complete screen-min-768.css File

/* Example: iPad portrait */
/* True if width greater than or equal to 768px */
body {background:#33CCCC;}
#container,
header,
#main article {padding: 2em;}
header h1 {
	font-size:3em;	
	line-height:1.2em;	
}
#main {
	float: left;
	width: 65%;
}
#featured {
	float: right;
	width: 35%;
	padding: 0 0 0 2em;
}
footer {clear:both;}

One Last @media Selector For Laptops and Desktop Widths

Once we hit the 1024 pixel width we are assuming a laptop or a desktop screen. In these case the operating systems have windows for displaying applications. The windows are resizable. The web browser is an application. So as the screens get wider, the user can max up the width to the point our design layout breaks apart like expanding outer space.

The usual solution to that is a maximum width.

Also we are going to have some viewport margins for these widths. That is outside the container div element.

The design calls for background image but not until we get to 1200 pixels wide. That may be that the viewing space for the image is not aesthetic until we get width. But it is a design choice. So we have another CSS media query to handle showing the background image at the chosen width which here is 1200 pixels.

Complete screen-min-1024.css File

/* Examples: iPad landscape, Laptops and Desktops */
/* True if width greater than or equal to 1024px */
body {background:#33CC33;}
#container {
	background-color:inherit;
	margin: 0 auto;
	max-width:1200px;
}
@media only screen and (min-width: 1200px) {
	body {background-image:url(weave_green_bg_100x100.png);}	
}

[ad name=”Google Adsense”]