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.

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.



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="viewport" content="width=device-width, initial-scale=1">
<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>
<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.</p>
		</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);}	
}



Mobile First Responsive Design with Media Queries External CSS Files


Previous | Part 4 of 5 | Next

By Lon Hosford
You have a plethora of configuration approaches with using CSS Media Queries in creating a mobile first design.log image for CSS Media Query 101 Mobile First Tutorial CSS Media Queries Mobile First Responsive Design External CSS Files The previous tutorials we places all the CSS into the HTML document. That was fine for a learning activity. You know that we need to use external CSS files. That means using the HTML link element in the document head section.

The @media CSS selector is just plain CSS so we can use it in an external CSS file. So all the CSS we had in the document style element can be put into a CSS file and it works the same.

Save 20% on Publish Your Flappy Bird Clone iPhone Game, EZ & No Coding!

Our CSS length was short and tailor for quick absorption in a learning activity. You can count on the CSS lines growing quickly as you start to include your design styling not only for one layout but possibly for multiple screen layouts. The CSS file can get pretty long. So you can consider an approach to break the CSS into separate files for each minimum screen width. Then you can just put the media query CSS in each file. This approach also works.

Then consider that the link element has the media attribute that uses the same media query syntax as the @media CSS selector. That allows you attach a CSS file only when the media query is true. It also negates the need for the media selector in the file. Essentially you are saying all the CSS in a file is for a specific group of screen widths starting at a certain minimum and expanding until another media query takes over any selectors and properties.

In this post we are taking the last example and breaking it up this way. One file for the base css and one file for each target minimum screen width.

Configuration Approaches and Refactoring Demonstration

This video covers the CSS Mobile First Responsive Design Configuration Approaches. It also demonstrates the refactoring of the last tutorial’s files into external files for the base and each target minimum screen width.



Source Files for the video series: Download

The link Element media Attribute

These are the link elements for each separate CSS file we plan to use.

  • base.css
  • screen-min-320.css
  • screen-min-768.css
  • screen-min-1024.css

The @media selector media query syntax is becomes the media attribute’s value. Then you order the files starting with the base followed by the CSS file for the smallest design width. The you progressively add the CSS files for each next minimum width target.

<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>

Save 20% on Master Your iPhone and Be 10X More Productive!

Each of the CSS files could contain the @media selector. If that was the case, then you do not need the link element media attribute.

A drawback is that we have increased number of network HTTP requests. Bandwidth performance is impacted by many items. Files do lend themselves to caching. So you need to perform your own bandwidth analysis to see if using multiple CSS files has any significant impact on your performance.

A happy medium might be one CSS file for the base and one for handling screen width detection.

  • base.css
  • screen.css

In that case you would include the @media selectors in the screen.css file.

Complete practice.html File

<!doctype html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<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>
<body>
	<header>
		<h1>Scriptum Titulus</h1>	
	</header>
	<section>
		<h2>Pagina Titulus</h2>
		<p>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. 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>	
	</section>
</body>
</html>

The CSS File Code

base.css

/* Base CSS */
header, section{ display: block; } 
/* All elements */
* {
	color:#FFF;
	margin:0;
	padding:0;
}
body { 
	background:#575757;
	font-family:Helvetica, Arial, sans-serif;
}
header h1 {
	background:rgba(0,0,0,.7);
	font-size:.8em;
	height: 3em;
	line-height:3em;
	padding:0 .5em;
}
section {
	margin:0 0 1em 0;
	padding:.6em;
}
section h2{
	font-size:.7em;
	padding-bottom:1em;
}
section p{
	font-size:.6em;
	padding-bottom:1em;
}

Save 20% on iPhone Camera Essentials!

screen-min-320.css

/* Smallest Screen Size Design Target */
/* Example: iPhone portrait */
/* True if width greater than or equal to 320px */
body {background:#B26BB2;}
header h1 {
	font-size:1.6em;	
	height:2.8em;
	line-height:2.8em;	
}
section {
	padding:.9em;
}
section h2{
	color:#000;
	font-size:1em;
}
section p{
	color:#000;
	font-size:.9em;
}

screen-min-768.css

/* Example: iPad portrait */
/* True if width greater than or equal to 768px */
body {background:#33CCCC;}
header h1 {
	font-size:1.8em;	
	height:3em;
	line-height:3em;	
}
section h2{
	font-size:1.5em;
}
section p{
	font-size:1.3em;
}

screen-min-1024.css

/* Examples: iPad landscape, Laptops and Desktops */
/* True if width greater than or equal to 1024px */
body {background:#FF0066;}
header h1 {
	font-size:2em;	
	height:3.2em;
	line-height:3.2em;	
}
section {
	max-width:1200px;
	padding:.9em;
}



Mobile First Responsive Design with Media Queries Using The CSS @media Selector


Previous | Part 3 of 5 | Next

By Lon Hosford
Media queries have a somewhat confusing syntax. This is typical as web page technologies evolve. Often there is a lot of forward thinking and features are added that may never become mainstream. So we need to sort out the parts of the syntax that are important to mobile first responsive design.

Blog image for CSS Media Query 101 Mobile First Tutorial Applying @media CSS Selector

Media queries can be added and using the CSS @media selector. The @media selector’s basic job is to create a test inside the CSS code. One of the tests is for the type of media.

Media Types

There is a keyword list for the media types web browsers may detect using media queries. The list includes all, aural, braille, embossed, handheld, print, projection, screen, speech, tty, andtv. Descriptions of these appear at the end of this article. We will use the screen type for mobile detection.

Media Type Properties (Features)

Then each media type has a potential of feature properties. We are not going to explore all of them other to mention the list which is color, color-index, aspect-ratio, device-aspect-ratio, device-height, device-width, grid, height, monochrome, orientation, resolution, scan, and width. Descriptions of each appear at the end of this article. Keep in mind they do not all apply to every media type and may apply to more than one media type. Also the feature properties may allow a min- or max- prefix. For example min-device-width or max-height.

For our purposes we are only interested in the width property. For our mobile first approach we will prefix as min-width.

Mobile First Responsive Design Step By Step

This video covers the media type and properties and applies them to the practice file.


Source Files for the video series: Download

Complete Starting Practice File

<!doctype html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>CSS Mobile Media Queries 101 | Lon Hosford</title>
<style type="text/css">
	header, section{ display: block; } 
	/* All elements */
	* {
		color:#FFF;
		margin:0;
		padding:0;
	}
	body { 
		background:#575757;
		font-family:Helvetica, Arial, sans-serif;
	}
	header h1 {
		background:rgba(0,0,0,.7);
		font-size:.8em;
		height: 3em;
		line-height:3em;
		padding:0 .5em;
	}
	section {
		margin:0 0 1em 0;
		padding:.6em;
	}
	section h2{
		font-size:.7em;
		padding-bottom:1em;
	}
	section p{
		font-size:.6em;
		padding-bottom:1em;
	}
</style>
</head>
<body>
	<header>
		<h1>Scriptum Titulus</h1>	
	</header>
	<section>
		<h2>Pagina Titulus</h2>
		<p>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. 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>	
	</section>
</body>
</html>

You see we already have the meta tag on line 5 that directs mobile web browsers to not resize the web page and fit it all within the device width.

 <meta name="viewport" content="width=device-width, initial-scale=1">

Then we have a base set of styles and selectors. These are minimal and you can expand on them for your own work. These styles appear as the default for all device widths. Also we want to design a single column view for the base. Fortunately that is the default for web browsers.

 <style type="text/css">
	header, section{ display: block; } 
	/* All elements */
	* {
		color:#FFF;
		margin:0;
		padding:0;
	}
	body { 
		background:#575757;
		font-family:Helvetica, Arial, sans-serif;
	}
	header h1 {
		background:rgba(0,0,0,.7);
		font-size:.8em;
		height: 3em;
		line-height:3em;
		padding:0 .5em;
	}
	section {
		margin:0 0 1em 0;
		padding:.6em;
	}
	section h2{
		font-size:.7em;
		padding-bottom:1em;
	}
	section p{
		font-size:.6em;
		padding-bottom:1em;
	}
</style>

The first query is for a 320 pixel width. As the comments show, this is the first width for devices like an iPhone. At this point it also will represent all widths over 320 pixels. Also we can refer to this as a break point.

We just are changing the background color for the body selector. Something simple like the body background color is a quick way to verify your media queries are working.

	/* Smallest Screen Size Design Target */
	/* Example: iPhone portrait */
	/* True if width greater than or equal to 320px */
	@media only screen and (min-width: 320px) {
		body {background:#B26BB2;}
	}

Next we add two more break points for 768 and 1024 pixels. In those we override the body selector background-color property.

	/* Example: iPad portrait */
	/* True if width greater than or equal to 768px */
	@media only screen and (min-width: 768px) {
		body {background:#33CCCC;}
	}
	/* Examples: iPad landscape, Laptops and Desktops */
	/* True if width greater than or equal to 1024px */
	@media only screen and (min-width: 1024px) {
		body {background:#FF0066;}
	}

This is the practice.html file completed to this point. You can open in your favorite browser.

<!doctype html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>CSS Mobile Media Queries 101 | Lon Hosford</title>
<style type="text/css">
	header, section{ display: block; } 
	/* All elements */
	* {
		color:#FFF;
		margin:0;
		padding:0;
	}
	body { 
		background:#575757;
		font-family:Helvetica, Arial, sans-serif;
	}
	header h1 {
		background:rgba(0,0,0,.7);
		font-size:.8em;
		height: 3em;
		line-height:3em;
		padding:0 .5em;
	}
	section {
		margin:0 0 1em 0;
		padding:.6em;
	}
	section h2{
		font-size:.7em;
		padding-bottom:1em;
	}
	section p{
		font-size:.6em;
		padding-bottom:1em;
	}
	/* Smallest Screen Size Design Target */
	/* Example: iPhone portrait */
	/* True if width greater than or equal to 320px */
	@media only screen and (min-width: 320px) {
		body {background:#B26BB2;}
	}
	/* Example: iPad portrait */
	/* True if width greater than or equal to 768px */
	@media only screen and (min-width: 768px) {
		body {background:#33CCCC;}
	}
	/* Examples: iPad landscape, Laptops and Desktops */
	/* True if width greater than or equal to 1024px */
	@media only screen and (min-width: 1024px) {
		body {background:#FF0066;}
	}
</style>
</head>
<body>
	<header>
		<h1>Scriptum Titulus</h1>	
	</header>
	<section>
		<h2>Pagina Titulus</h2>
		<p>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. 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>	
	</section>
</body>
</html>

If that browser has a responsive design viewer like Firefox, then try the different breakpoints. Otherwise you can resize the width of the web browser for an approximation.

As you do, try widths between the breakpoints and you can see the web browser default flexible rendering of block tags has the text wrap and unwrap as you adjust sizes. Notice that the background color remains the same within the breakpoints.

Understanding Responsive Design Changes

Changing the background color at breakpoints is interesting but is not the most probably design change you want to achieve for various breakpoints. You will want to change styling such as sizes of fonts , margins, padding and line-heights for example. Smaller fonts for narrow widths and larger fonts for wider widths. Less padding and margins for smaller widths and take advantage of the screen real estate of larger widths with more padding and margins.

You also may want different layouts. Narrow widths are likely to render a better experience for users if you design a single column layout. Then for the wider widths, you can introduce multiple column layouts.

For this article are just going to demonstrate some basic style changes to font sizes, font-color, padding and line-heights. In a future article we will experiment with a basic layout change.

Here are the changes:

	/* Smallest Screen Size Design Target */
	/* Example: iPhone portrait */
	/* True if width greater than or equal to 320px */
	@media only screen and (min-width: 320px) {
		body {background:#B26BB2;}
		header h1 {
			font-size:1.6em;	
			height:2.8em;
			line-height:2.8em;	
		}
		section {
			padding:.9em;
		}
		section h2{
			color:#000;
			font-size:1em;
		}
		section p{
			color:#000;
			font-size:.9em;
		}
	}
	/* Example: iPad portrait */
	/* True if width greater than or equal to 768px */
	@media only screen and (min-width: 768px) {
		body {background:#33CCCC;}
		header h1 {
			font-size:1.8em;	
			height:3em;
			line-height:3em;	
		}
		section h2{
			font-size:1.5em;
		}
		section p{
			font-size:1.3em;
		}
	}
	/* Examples: iPad landscape, Laptops and Desktops */
	/* True if width greater than or equal to 1024px */
	@media only screen and (min-width: 1024px) {
		body {background:#FF0066;}
		header h1 {
			font-size:2em;	
			height:3.2em;
			line-height:3.2em;	
		}
		section {
			max-width:1200px;
			padding:.9em;
		}
	}	

You might want to turn your attention to the 1024 pixel breakpoint. There we are capping the width of the section selector. The idea is to keep the text from unwrapping for very large monitors. Some assumptions about content are going to go into such a choice. In our case it is arbitrary for demonstration.

But you will need to think about the base view and the largest break point extremes. The base view is for devices you have not considered below the first breakpoint. The design can be what every you want to put time and energy into creating or you may just want a near print ready styling. The widest breakpoint needs to handle the extreme widths.

Here is the completed practice file.

<!doctype html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>CSS Mobile Media Queries 101 | Lon Hosford</title>
<style type="text/css">
	header, section{ display: block; } 
	/* All elements */
	* {
		color:#FFF;
		margin:0;
		padding:0;
	}
	body { 
		background:#575757;
		font-family:Helvetica, Arial, sans-serif;
	}
	header h1 {
		background:rgba(0,0,0,.7);
		font-size:.8em;
		height: 3em;
		line-height:3em;
		padding:0 .5em;
	}
	section {
		margin:0 0 1em 0;
		padding:.6em;
	}
	section h2{
		font-size:.7em;
		padding-bottom:1em;
	}
	section p{
		font-size:.6em;
		padding-bottom:1em;
	}
	/* Smallest Screen Size Design Target */
	/* Example: iPhone portrait */
	/* True if width greater than or equal to 320px */
	@media only screen and (min-width: 320px) {
		body {background:#B26BB2;}
		header h1 {
			font-size:1.6em;	
			height:2.8em;
			line-height:2.8em;	
		}
		section {
			padding:.9em;
		}
		section h2{
			color:#000;
			font-size:1em;
		}
		section p{
			color:#000;
			font-size:.9em;
		}
	}
	/* Example: iPad portrait */
	/* True if width greater than or equal to 768px */
	@media only screen and (min-width: 768px) {
		body {background:#33CCCC;}
		header h1 {
			font-size:1.8em;	
			height:3em;
			line-height:3em;	
		}
		section h2{
			font-size:1.5em;
		}
		section p{
			font-size:1.3em;
		}
	}
	/* Examples: iPad landscape, Laptops and Desktops */
	/* True if width greater than or equal to 1024px */
	@media only screen and (min-width: 1024px) {
		body {background:#FF0066;}
		header h1 {
			font-size:2em;	
			height:3.2em;
			line-height:3.2em;	
		}
		section {
			max-width:1200px;
			padding:.9em;
		}
	}
</style>
</head>
<body>
	<header>
		<h1>Scriptum Titulus</h1>	
	</header>
	<section>
		<h2>Pagina Titulus</h2>
		<p>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. 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>	
	</section>
</body>
</html>

Media Types Reference

all
Simple for all devices.
aural
CSS2 version of speech
braille
Tactile braille devices.
embossed
Intended for paged braille printers.
handheld
Early choice for detecting small screen devices with low bandwidth capability.
print
For printing.
projection
Devices that facilitate projection of presentation. The typical projector is and example.
screen
Color computer screens.
speech
Devices that can synthesize speech. Compare to aural in CSS2.
tty
Fixed character width grid devices like teletypes and terminals. Devices usually have limited display features.
tv
Television like devices.

Media Types Features Reference

color1
Number of bits per color.
color-index1
Number of entries in the color look-up table.
aspect-ratio1
The display area ratio of the horizontal pixels to vertical pixels. Expressed as two unsigned integers separated by a slash.
device-aspect-ratio1
The output device area ratio of the horizontal pixels to vertical pixels. Expressed as two unsigned integers separated by a slash
device-height1
The output device height.
device-width1
The output device width.
grid
True if a grid device or a bitmap device is detected. For example a phone or teletype.
monochrome1
Detects the number of bits per pixel on a monochrome device.
height1
The rendering area height.
orientation
Tests for the values landscape or portrait.
resolution1
Pixel density of the device expressed as dots per inch (dpi) or dots per centimeter (dpcm).
scan
Tests for the values progressive or interlaced.
width1
The rendering area width.

1 Supports min- and max- prefix.


Mobile First Responsive Design with Media Queries Setting the Viewport


Previous | Part 2 of 5 | Next

By Lon Hosford
Mobile web browsers may scale down your web page. That can result in an unattractive and
unreadable content. They may show a partial width of your page.

Blog image for CSS Media Query 101 Mobile First Tutorial Viewports and Scaling

This makes the user resize and horizontally scroll your page. Or worse they might just hit the back button. You may find that these default behaviors of mobile web browsers render the work that you put into designing your page ineffective. So let’s look at this problem and the simple HTML tag to correct it.

The Viewport
The viewport represents the boundaries of the part of the content you can see. NOAA Weather Page IPhoneThe content you cannot see you might say is “off screen”. It is actually masked by the boundaries of the viewport as on the right screen shot of the NOAA website.

The web browser window in a typical laptop and desktop is the viewport of your web pages. Of course laptops and desktop screens also present themselves as a viewport for running windows.

For most mobile devices the web browser does not have a window in the same respect does a web browser on a laptop or desktop. Often the web browser viewport is the actual width and height of the device. So unlike a desktop where you can position the web browser partially off screen, you cannot do that with a mobile web browser.

Mobile web browsers will make some assumptions about your web page if it does not already fit within the dimensions of the device viewport. This could be how much it scales and what percentage of the width it wants in the viewport width.

You can visit the web browser web sites to find out exactly how that works. But why bother unless you do not plan to design or redesign your web page to fit within the viewport. For a field trip you can visit the Safari Viewport Configuration Web Page.

The HTML meta Tag for Viewport

The HTML meta tag is used to override the mobile web browser’s default calculations for dimensions and scaling. The name attribute is set to viewport. The content attribute contains a number properties expressed as name value pair options separated by commas. The two properties you need are width and initial-scale.

The width property is set to device-width. The initial-scal property is set to 1.

Here is the completed meta tag line.

 <meta name="viewport" content="width=device-width, initial-scale=1">

The width is in pixels. The initial-scale is actually a multiplier. Without setting other content properties, one means really no scaling.

The other content properties include height minimum-scale, maximum-scale and user-scalable.

The minimum-scale, maximum-scale properties are the minimum and maximum viewport scales with a range. For Safari mobile web browser that range is 0-10.

The user-scalable property determines whether or not the user can zoom in and out to change the scale of the viewport. Values are yes and no.

Here is the meta tag in the head section of your HTML.

<!doctype html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>CSS Mobile Media Queries 101 | Lon Hosford</title>

Examples and Demo

If you are following along with the series, we are adding the meta tag for the viewport. This video reviews the problem, presents some examples of the problem, discusses the viewport meta tag properties and adds the single line to our practice file.

Source Files for the video series: Download


Blog post icon for Creating a Simple Debugging Library

Creating a Simple PHP Debug Library


By Lon Hosford
I like to have a plan for debugging from the start. That usually means a debugging library. Debugging libraries can be simple and can be complex.

Blog post icon for Creating a Simple Debugging Library
Blog post icon for Creating a Simple Debugging Library
They can be procedural and they can be object oriented. No matter which approach, having something that is generic to your applications you can drop in is the minimum before coding. In particular a debugging library is handy when you inherit another PHP project where there is no breadcrumb on how testing and debugging was handled.

This is an example of a minimalist framework for a debugging library and testing dashboard. It is great for those first learning to program in PHP. I like to use it for teaching PHP.

There is a lot we can add to the library such as routing log messages to the UI or to a log file of your choice. But you can build these features onto this library by adding constants, functions and if needed global space variables.

Source Files: Download

The Debug Common Library – debug_common.inc.php

This is the minimal debug library.

<?php
/**
 *	Debugging configuration.
 *	
 *	Search all source files for **PRODUCTION SETTING** for production settings
 *  @author Lon Hosford 
 *  @link www.lonhosford.com 
 *	@copyright 2014 Alonzo Hosford
 *  @license GPL 
*/
/**
 *	Send runtime errors to stdout(1) vs stderr (0)
 *	**PRODUCTION SETTING** = 0
 */
ini_set('display_errors', 1);
/**
 *	Send startup errors to stdout(1) vs stderr (0)
 *	**PRODUCTION SETTING** = 0
 */
ini_set('display_startup_errors', 1);
/**
 *	PHP levels of error reporting
 *   0 = off
 *   E_ERROR | E_WARNING | E_PARSE = simple running errors
 *   E_ERROR | E_WARNING | E_PARSE | E_NOTICE = E_NOTICE adds uninitialized variables or catch variable name misspellings
 *   -1 or E_ALL = all errors
 *	**PRODUCTION SETTING** = 0
 */
error_reporting(E_ALL);
?>

The first important item to notice is the use of the search tag, **PRODUCTION SETTING**. It is important for documenting code changes necessary for moving code to other environments such as staging, pre-production and production.

 *	**PRODUCTION SETTING** = 0

You use a file search for **PRODUCTION SETTING** and examine the documentation for changing code to necessary values. If you have something different from production you can create other ways such as a separate search tag for each environment or a generic search tag that will document each environment.

Line 15 allows the override to the PHP configuration property display_errors for displaying errors with the PHP output.

ini_set('display_errors', 1);

The PHP ini_set function sets PHP runtime configuration values and takes the name of the configuration property as the first parameter and the value as the second parameter.

In this case any error messages from PHP are included in the output from PHP. This is regardless of the output format. So if it is a web page, the errors are mixed into the page. You may or may not see them as they could be stuck in the page header section. And this also means if the output is JSON, XML, NVP or any format, the errors ride along often spoiling the parser receiving the output.

Line 20 includes any errors that are generated from PHP starting. This is less common on a well tested hosting site running PHP. But I included just in case as if the error is not in your code it may show here.

ini_set('display_startup_errors', 1);

The final item is to filter the category levels of PHP errors. The usual choices are 0 for off and the constant E_ALL for all levels.

error_reporting(E_ALL);

You can include bitwise operations to combine the other constants listed in the comments. You may find that helpful when inheriting code with many errors to filter out key errors to flesh out, third party code or you have created an error that cascaded a multitude of errors. Avoid that latter situation with test often and in small code units.

468X60
Application Common Library – lib_common.inc.php
<?php
/**
 *	Library for common database configuration, data and initalizations.
 *
 *	Include before running other scripts.
 *	Search all files for **PRODUCTION SETTING** for production settings
 *	@author Lon Hosford 
 *  @link www.lonhosford.com 
 *	@copyright 2014 Alonzo Hosford
 *  @license GPL 
 */
/**
 *	Include debugging configuration
 *
 *	@see debug_common.inc.php
 */
include_once "debug_common.inc.php";
/**
 *	Initialize use of session tracking and the PHP $_SESSION var.
 */
session_start();
/**
 *	Set the timezone.
 */
date_default_timezone_set('America/New_York');
/**
 *	Required PHP version
 */
const VERSION_PHP = "5.3.1";
?>

Your PHP applications should have a common code block for application level variables, constants and functions. This could be a singleton OOP class or a simple procedural file.

The main point is to have the first loaded coded here and keep it clean of debugging specific code.

Also this is where I document code search tags used to set values when moving code between environments.

 *	Search all files for **PRODUCTION SETTING** for production settings

The debugging library is hooked into this file as early as possible. Generally you can leave this line of code for other environments but if you want to comment it for those environments, add your search tag in the comments with the instructions for doing that.

include_once "debug_common.inc.php";

[/code]
An advantage to a one line addition of a debugging library is you can have multiple versions of the debugging library and swap them here.

The session_start line has no impact on debugging. It shown as a common first line of code in a common library.

session_start();

Same situation with date_default_timezone_set function. This is just making it clear the server running PHP should use that specific time zone for handling date and time computations.

date_default_timezone_set('America/New_York');

I prefer to include all the constants for library versions in the common application library starting with the PHP version. Here I use VERSION_PHP and just prefix all the version constant names with VERSION_PHP.

const VERSION_PHP = "5.3.1";

You may want similar constants for other libraries such as MySQL, PHPMailer or a PayPal library.

At the minimum you can use these constants in a debug test to see if the versions are correct. Also you can use them in application code to take action if they are not correct.

Debugging and Testing Dashboard – debug_dashboard.php
<?php
/**
 *	The debug library demonstration and testing.
 *
 *  @author Lon Hosford 
 *  @link www.lonhosford.com 
 *	@copyright 2014 Alonzo Hosford
 *  @license GPL 
*/
include_once "lib_common.inc.php";
?>
<!doctype html>
<html>
<head>
	<meta charset="UTF-8">
	<title>Testing and Debugging Dashboard | lonhosford.com</title>
	<style>
	body{ font-family:"Gill Sans", "Gill Sans MT", "Myriad Pro", "DejaVu Sans Condensed", Helvetica, Arial, sans-serif}
	pre {
	 white-space: pre-wrap;       /* css-3 */
	 white-space: -moz-pre-wrap;  /* Mozilla, since 1999 */
	 white-space: -pre-wrap;      /* Opera 4-6 */
	 white-space: -o-pre-wrap;    /* Opera 7 */
	 word-wrap: break-word;       /* Internet Explorer 5.5+ */
	}
	.mono-space{font-family:monospace;}
	table,td {border:solid 1px #000;}
	</style>
</head>
<body>
<h2>Testing and Debugging Dashboard </h2>
<h4><a href="<?php echo $_SERVER['PHP_SELF'];?>"><?php echo basename(__FILE__);?></a></h4>
<hr>
<pre>
<?php 
echo "PHP Version Required: " . VERSION_PHP . "\n";
echo "PHP Version Detected: " . phpversion() . "\n";
echo "PHP Version is <strong>" . (version_compare(phpversion(), VERSION_PHP, '>=') ? "": "IN") . "VALID</strong>." . "\n";
echo "Display date/time: " .  date('m/d/Y h:i:s a', time()) . "\n";
echo "Display display_errors: " . ini_get("display_errors") . "\n";
echo "Display display_startup_errors: " . ini_get("display_startup_errors") . "\n";
echo "Display error_reporting(): " . error_reporting() . "\n";
?>
</pre>
</body>
</html>

This last file is really a simple testing and debugging script. There are various levels of sophistication for testing in all programming languages.

At the minimum, you should have a script or scripts that can run independently from your application, which means these scripts are loaded separately, and perform tests. If you an automate them, the better. They will include your code of course and by doing so you will start on your way to unit testing or at least testing smaller parts of your code and thus forced to write your code in more modular units.

I did not include any examples of testing application code here, but there is a hint of a permutation in the video. I often have several files all included into this file. The separate files target testing a specific part of the code. All tests lean towards unit testing.

Also this is a great place for general debugging information.

Here I am showing the PHP version,

echo "PHP Version Required: " . VERSION_PHP . "\n";
echo "PHP Version Detected: " . phpversion() . "\n";
echo "PHP Version is <strong>" . (version_compare(phpversion(), VERSION_PHP, '>=') ? "": "IN") . "VALID</strong>." . "\n";

timezone information.

echo "Display date/time: " .  date('m/d/Y h:i:s a', time()) . "\n";

and debugging library settings.

echo "Display display_errors: " . ini_get("display_errors") . "\n";
echo "Display display_startup_errors: " . ini_get("display_startup_errors") . "\n";
echo "Display error_reporting(): " . error_reporting() . "\n";
?>

In the end, the running of this script highlights key settings that everyone scrambles to check before or worse after moving code to another environment. So running this script becomes a check list item before making those moves.



Understanding How WordPress Works Free Webinar March 5th 2914

Webinar On Understanding How WordPress Works

By Lon Hosford
I am often asked in my Web Development Courses about WordPress. For many students who want to get started on the Internet quickly, this could be a good approach. wordpress_icon_violet_14_02_22_600x600So I did a series of webinars on WordPress.

The goal was to over some general topics to provide an overview. Here is the topic list.

  • WordPress Session 1 Introduction
  • WordPress DIY Installation and Hosting
  • WordPress Administrative Panel and Posting Overview
  • WordPress Session 1 Q&A
  • WordPress Session 2 Introduction
  • WordPress User Accounts Roles and Capabilities
  • WordPress Create and Edit Posts
  • WordPress Categories and Tags
  • WordPress Permalinks
  • WordPress Post Formats
  • WordPress Polls Ratings

There is a page filled with research links;

Understanding WordPress Research Links

And if you are looking for a full how to do it course you might look at

PHP Logo with RecursiveDirectoryIterator

How to Recursively Traverse File Directories with PHP RecursiveDirectoryIterator


By Lon Hosford
You can avoid writing recursive function to traverse through tree structures like you server file system. PHP has several Iterator classes starting with version 5. PHP Logo with  RecursiveDirectoryIterator

In this article we will look at the RecursiveDirectoryIterator class. We will build a utility function to use the RecursiveDirectoryIterator class to provide a text listing of the path and file names in one or more directories.

Although we are just displaying paths to the files, you can also access the file information such as modification date, creation date, size, permissions and a variety of properties through the parent classes of RecursiveDirectoryIterator. Those classes include in order of inheritance: FilesystemIterator, DirectoryIterator and SplFileInfo. SplFileInfo provides many of the global file functions in PHP such as isDir, is_readable is_writeable and is_real for example.

Source Files: Download

Video Tutorial:

The User Interface – test_debug_dir_list.php

There is a simple hybrid HTML PHP script, test_debug_dir_list.php, to demonstrate. It has five tests using a customized function for RecursiveDirectoryIterator.

test_debug_dir_list.php in browser no links chosen
This is the first test showing all the file and directories in the folder that test_debug_dir_list.php is in.

test_debug_current_dir in browser first test link chosen

The second test showing all the file and directories in the folder that test_debug_dir_list.php and of all its child directories.

test_debug_current_dir_1 in browser second test link chosen

The third links shows the files and directories of the parent directory for test_debug_dir_list.php.

test_debug_parent_dir in browser third test link chosen

This fourth test link is like the third but includes the first level of children directories for the parent directory.

test_debug_parent_dir_1 in browser third test link chosen

This fifth link test one more child directory level than the fourth.

test_debug_parent_dir_2 in browser third test link chosen

Custom Function debug_dir_list Using RecursiveDirectoryIterator

The function parameters on line 17 are the depth levels for recursing file system directories and the starting file system directory.

The default file system directory is the running script that might include debug_utils.inc.php contain our function. You can use the standard file system notation to express parent directories and paths.

The depth levels are the exact values for the RecursiveIteratorIterator class instance created on line 23. A negative one recurses to the last lowest level. Be careful with that on a big file system where the second argument is the root or near it. The debug_dir_list default value is zero which confines the RecursiveIteratorIterator instance to the starting files system directory.

debug_utils.inc.php – parameters

function debug_dir_list($dir_recurse_depth = 0, $dir_list_root = '.'){

Lines 19 to 21 creates the RecursiveDirectoryIterator instance. It has to arguments. The first, on line 20, is the starting directory and we use the debug_dir_list function’s second parameter without change. The second RecursiveDirectoryIterator instance parameter is a set of flags. We are using the flag to suppress showing the single and double dot files.

debug_utils.inc.php – The RecursiveDirectoryIterator Instance

	// Create a recursive file system directory iterator.
	$dir_iter = new RecursiveDirectoryIterator(
		$dir_list_root, 
		RecursiveDirectoryIterator::SKIP_DOTS) ;// Skips dot files (. and ..)

Lines 23 to 27 create the RecursiveIteratorIterator class instance. Its first parameter on line 24 requires a class with a traversal iterator class and RecursiveDirectoryIterator implements the RecursiveIterator interface to meet that requirement.

The second argument on line 25 for the RecursiveIteratorIterator constructor is called mode. There are three modes that are constants to the class.

  • RecursiveIteratorIterator::LEAVES_ONLY – The default. Lists only leaves in iteration.
  • RecursiveIteratorIterator::SELF_FIRST – Lists leaves and parents in iteration with parents coming first.
  • RecursiveIteratorIterator::CHILD_FIRST – Lists leaves and parents in iteration with leaves coming first.

The RecursiveIteratorIterator constructor’s third argument on line 26 is called modes. It is optional and currently only has its own RecursiveIteratorIterator::CATCH_GET_CHILD as a possible value which will then ignore exceptions thrown such as denied file permissions.

Line 29 passed the recursion depth through the RecursiveIteratorIterator class setMaxDepth method. Here to the debug_dir_list function’s parameter is passed unchanged.

debug_utils.inc.php – The RecursiveIteratorIterator Instance

	// Create a recursive iterator.
	$iter = new RecursiveIteratorIterator(
		$dir_iter, 
		RecursiveIteratorIterator::SELF_FIRST, // Lists leaves and parents in iteration with parents coming first.
		RecursiveIteratorIterator::CATCH_GET_CHILD // Ignore exceptions such as "Permission denied"
		);
	// The maximum recursive path.
	$iter->setMaxDepth($dir_recurse_depth);

The rest of the function uses the RecursiveIteratorIterator to iterate its objects which have a base class of SplFileInfo. These objects resolve as the path string. But also you can see on line 33, they have the method isDir which is like the standalone is_file function. If you explore the SplFileInfo class you can see all the other methods for file system objects. Line 31 is really just adding for visual purposes a trailing slash to objects that are a directory and not the starting directory.

Line 34 pushes that $path string onto the $paths array which is returned from the debug_dir_list function.

debug_utils.inc.php

	// List of paths Include current paths
	$path = array($dir_list_root);
	foreach ($iter as $path => $dir) {
		if ($dir_recurse_depth == 0 && $dir->isDir()) $path .= "/";
		$paths[] = substr($path,2);
	}
	return $paths;

debug_utils.inc.php – full listing

<?php
/**
 *	Utilitites to help in debugging.
 * 
 *	@author Lon Hosford 
 *	@link www.lonhosford.com 
*/
/**
 *	Create an array of files and directory names, Requires PHP 5 >= 5.3.1.
 *
 *	Directories without contents have a slash appended or at the $dir_recurse_depth regardless if they have contents. Hidden files and folders are included.
 *	@link http://stackoverflow.com/questions/14304935/php-listing-all-directories-and-sub-directories-recursively-in-drop-down-menu This code is based on this Stackoverflow post.
 *	@param int $dir_recurse_depth recurse depth. 0 for $dir_list_root. Add 1 for each child level.  -1 is used for any depth.
 *	@param string $dir_list_root recurse depth. Starting folder path. Files in this directory are included. Default is current directory. 
 *	@return string[] List of folders and files found.
 */
function debug_dir_list($dir_recurse_depth = 0, $dir_list_root = '.'){
	// Create a recursive file system directory iterator.
	$dir_iter = new RecursiveDirectoryIterator(
		$dir_list_root, 
		RecursiveDirectoryIterator::SKIP_DOTS) ;// Skips dot files (. and ..)
	// Create a recursive iterator.
	$iter = new RecursiveIteratorIterator(
		$dir_iter, 
		RecursiveIteratorIterator::SELF_FIRST, // Lists leaves and parents in iteration with parents coming first.
		RecursiveIteratorIterator::CATCH_GET_CHILD // Ignore exceptions such as "Permission denied"
		);
	// The maximum recursive path.
	$iter->setMaxDepth($dir_recurse_depth);
	// List of paths Include current paths
	$path = array($dir_list_root);
	foreach ($iter as $path => $dir) {
		if ($dir_recurse_depth == 0 && $dir->isDir()) $path .= "/";
		$paths[] = substr($path,2);
	}
	return $paths;
}
?>	
The User Interface – Exploring the source of test_debug_dir_list.php

For the UI script line 10 imports our debug_dir_list function.

test_debug_dir_list.php

include_once "debug_utils.inc.php";

Line 32 and lines 35 to 40 provide a url link back to test_debug_dir_list.php. Lines 35 to 40 provide a NVP (Name Value Pair) for the URL query and line 32 omits that. The NVP name is debug-action and the values current_dir, current_dir_1, parent_dir, parent_dir_1 and parent_dir_2.

test_debug_dir_list.php

<h3>debug_dir_list($dir_recurse_depth = 0, $dir_list_root = '.')</h3>
<ol class = 'mono-space'>
	<li><a href="<?php echo $_SERVER['PHP_SELF'] . '?debug-action=current_dir';?>">Run</a> - List Current Directory - debug_dir_list()</li>
	<li><a href="<?php echo $_SERVER['PHP_SELF'] . '?debug-action=current_dir_1';?>">Run</a> - List Current Directory + Children(1) - debug_dir_list(1)</li>
	<li><a href="<?php echo $_SERVER['PHP_SELF'] . '?debug-action=parent_dir';?>">Run</a> - List Parent Directory  + Children(0) - debug_dir_list(0, "../")</li>
	<li><a href="<?php echo $_SERVER['PHP_SELF'] . '?debug-action=parent_dir_1';?>">Run</a> - List Parent Directory + Children(1) - debug_dir_list(1, "../")</li>
	<li><a href="<?php echo $_SERVER['PHP_SELF'] . '?debug-action=parent_dir_2';?>">Run</a> - List Parent Directory + Children(2) - debug_dir_list(2, "../")</li>
</ol>

Lines 44 to 48 interrogate the super global $_GET variable for the debug-action key and sets the $get_action variable either as an empty string or the value in the $_GET['debug-action'] variable. There is no need to sanitize here as this is for internal development and testing and not a production script.

test_debug_dir_list.php

<?php 
if ( !isset($_GET["debug-action"]) ){
	$get_action = "";
}else{
	$get_action = $_GET["debug-action"];
}

Lines 52 to 68 a switch block sets out each of the debug-action values and echoes the results of the debug_dir_list function with parameters to meet the desired results.

test_debug_dir_list.php

switch($get_action){
	case 'current_dir':
		echo "File list: " . print_r(debug_dir_list(), true);
	break;
	case 'current_dir_1':
		echo "File list: " . print_r(debug_dir_list(1), true);
	break;
	case 'parent_dir':
		echo "File list : " . print_r(debug_dir_list(0, "../"), true);
	break;
	case 'parent_dir_1':
		echo "File list: " . print_r(debug_dir_list(1, "../"), true);
	break;
	case 'parent_dir_2':
		echo "File list: " . print_r(debug_dir_list(2, "../"), true);
	break;
}

Worth a mention are lines 49 to 51. They help debug the debugging. The file name is helpful on line 49 when you are bleary eyed and not sure which testing script you are running. The basename function passed the magic constant __FILE__ provides the file name of this script. In face you might want to add a line use display the magic constant __FILE__. Testing scripts can get spread around and copied when the coding battle to finish gets wild.

Along with that heat of the battle information is the PHP version in front of your eyes. Line 50 does that. There is always the situation that a “temporary” server is needed to run some tests and no one bothers to check the PHP version installed. The phpversion function is just the ticket.

Then to check this debugging program is passing the expected debug-action value, we throw that out on line 51.

test_debug_dir_list.php

echo basename(__FILE__) . "\n";
echo "PHP version: " . phpversion() . "\n";
echo "debug-action=" . $get_action . "\n";

test_debug_dir_list.php – full listing

<?php
/**
 *	The debugging dashboard for testing and development.
 *
 *  @author Lon Hosford 
 *  @link www.lonhosford.com 
 *	@copyright 2014 Alonzo Hosford
 *  @license GPL 
*/
include_once "debug_utils.inc.php";
?>
<!doctype html>
<html>
<head>
	<meta charset="UTF-8">
	<title>Testing and Debugging Dashboard | lonhosford.com</title>
	<style>
	body{ font-family:"Gill Sans", "Gill Sans MT", "Myriad Pro", "DejaVu Sans Condensed", Helvetica, Arial, sans-serif}
	pre {
	 white-space: pre-wrap;       /* css-3 */
	 white-space: -moz-pre-wrap;  /* Mozilla, since 1999 */
	 white-space: -pre-wrap;      /* Opera 4-6 */
	 white-space: -o-pre-wrap;    /* Opera 7 */
	 word-wrap: break-word;       /* Internet Explorer 5.5+ */
	}
	.mono-space{font-family:monospace;}
	table,td {border:solid 1px #000;}
	</style>
</head>
<body>
<h2>Testing and Debugging Dashboard</h2>
<h4><a href="<?php echo $_SERVER['PHP_SELF'];?>"><?php echo basename(__FILE__);?></a></h4>
<h3>debug_dir_list($dir_recurse_depth = 0, $dir_list_root = '.')</h3>
<ol class = 'mono-space'>
	<li><a href="<?php echo $_SERVER['PHP_SELF'] . '?debug-action=current_dir';?>">Run</a> - List Current Directory - debug_dir_list()</li>
	<li><a href="<?php echo $_SERVER['PHP_SELF'] . '?debug-action=current_dir_1';?>">Run</a> - List Current Directory + Children(1) - debug_dir_list(1)</li>
	<li><a href="<?php echo $_SERVER['PHP_SELF'] . '?debug-action=parent_dir';?>">Run</a> - List Parent Directory  + Children(0) - debug_dir_list(0, "../")</li>
	<li><a href="<?php echo $_SERVER['PHP_SELF'] . '?debug-action=parent_dir_1';?>">Run</a> - List Parent Directory + Children(1) - debug_dir_list(1, "../")</li>
	<li><a href="<?php echo $_SERVER['PHP_SELF'] . '?debug-action=parent_dir_2';?>">Run</a> - List Parent Directory + Children(2) - debug_dir_list(2, "../")</li>
</ol>
<hr>
<pre>
<?php 
if ( !isset($_GET["debug-action"]) ){
	$get_action = "";
}else{
	$get_action = $_GET["debug-action"];
}
echo basename(__FILE__) . "\n";
echo "PHP version: " . phpversion() . "\n";
echo "debug-action=" . $get_action . "\n";
switch($get_action){
	case 'current_dir':
		echo "File list: " . print_r(debug_dir_list(), true);
	break;
	case 'current_dir_1':
		echo "File list: " . print_r(debug_dir_list(1), true);
	break;
	case 'parent_dir':
		echo "File list : " . print_r(debug_dir_list(0, "../"), true);
	break;
	case 'parent_dir_1':
		echo "File list: " . print_r(debug_dir_list(1, "../"), true);
	break;
	case 'parent_dir_2':
		echo "File list: " . print_r(debug_dir_list(2, "../"), true);
	break;
}
?>	
</pre>
</body>
</html>



xampp_in_envelope_150x96

How to Send Email From XAMPP using localhost on a Mac and your Gmail Account


By Lon Hosford

This is sample code for using SMTP and your Google GMail account with XAMPP installed on a Mac and PHPMailer.xampp_in_envelope_150x96
Often you want to send mail from your web site to yourself from a user form or even to others. But you may be using XAMPP as a local host and want to test that without having to upload to a public server. This script shows how you can do that with PHPMailer.

Step 1: Install XAMPP MacOS

Step 2: Download PHPMailer

Step 3: Create a testing php file shown below. Be sure you have the correct paths to class.phpmailer.php and class.smtp.php on lines 3 and 4 that you downloaded with PHPMailer.

<!--?php 
include("class.phpmailer.php"); 
include("class.smtp.php"); 
function test_gmail_smtp_basic() {
 	// Uncomment as needed for debugging
 	//error_reporting(E_ALL);
  	//error_reporting(E_STRICT);
 	// Set as needed
	date_default_timezone_set('America/New_York');
	$mail = new PHPMailer(); 
	// Optionally get email body from external file
 	$body = file_get_contents('contents.html');
 	$body = eregi_replace("[\]",'',$body);
  	$mail->IsSMTP();                            // telling the class to use SMTP
	$mail->Host       = "smtp.gmail.com";       // SMTP server
	$mail->SMTPDebug  = 2;                      // enables SMTP debug information (for testing)
                                                    // 0 default no debugging messages
                                                    // 1 = errors and messages
                                                    // 2 = messages only
	$mail->SMTPAuth   = true;                   // enable SMTP authentication
	//$mail->SMTPSecure = 'ssl';                // Not supported
	$mail->SMTPSecure = 'tls';                  // Supported
	$mail->Host       = "smtp.gmail.com";       // sets the SMTP server
	$mail->Port       = 587;                    // set the SMTP port for the GMAIL server
	$mail->Username   = "me@gmail.com";         // SMTP account username (how you login at gmail)
	$mail->Password   = "mygmailpassword";      // SMTP account password (how you login at gmail)

	$mail->setFrom('mememe@gmail.com', 'Joe Dirt');

	$mail->addReplyTo('mememe@gmail.com', 'Joe Dirt");

	$mail->Subject    = "PHPMailer Test Subject via smtp, basic with authentication";

	$mail->AltBody    = "To view the message, please use an HTML compatible email viewer!"; // optional, comment out and test

	$mail->msgHTML($body);

	$address = "someone-else@their-email-domain.com";
	$mail->addAddress($address, "Miss Piggy");
	// if you have attachments
	$mail->addAttachment("phpmailer.gif");      // attachment 
	$mail->addAttachment("phpmailer_mini.gif"); // attachment

	if(!$mail->Send()) {
	  echo "Mailer Error: " . $mail->ErrorInfo;
	} else {
	  echo "Message sent!";
	}
}
// Test the connection
test_gmail_smtp_basic();
?>

What you may find is an issue with many examples heretofore is that SMTPSecure shown on line 25 needs to be TLS (Transport Layer Security) instead of SSL (Secure Sockets Layer). The other item is the port number is 587 as you see on line 29. You can disable line 29 once you have this fully debugged. Use with care. 

These images come with PHPMailer and are included here for your convenience.

phpmailer.gif

phpmailer.gif

Optional external html file for the body content. See line 12 in the code above.

<body style="margin: 10px;">
<div style="width: 640px; font-family: Arial, Helvetica, sans-serif; font-size: 11px;">
<div align="center"><img style="height: 90px; width: 340px;" alt="" src="phpmailer.gif" /></div><br>
<br>
&nbsp;This is a test of PHPMailer.<br>
<br>
This particular example uses <strong>HTML</strong>, with a <div> tag and inline<br>
styles.<br>
<br>
Also note the use of the PHPMailer logo above with no specific code to handle
including it.<br />
Included are two attachments:<br />
phpmailer.gif is an attachment and used inline as a graphic (above)<br />
phpmailer_mini.gif is an attachment<br />
<br />
PHPMailer:<br />
Author: Lon Hosford (somebody@no.net)
</div>
</body>



Web Development Training