<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0">
<channel>
<title>johna's blog</title>
<link>https://johna.compoutpost.com/</link>
<description>...mostly about web development and programming, with a little bit of anything else related to the Internet, computers and technology.</description>
<item>
<title>Responsive collapsing search filters in Bootstrap 4</title>
<link>https://johna.compoutpost.com/blog/950/responsive-collapsing-search-filters-in-bootstrap-4/</link>
<description>&lt;img alt=&quot;Responsive collapsing search filters in Bootstrap &quot; src=&quot;/blog/uploads/img950_bootstrap-responsive-collapsing-search-filters.jpg&quot; class=&quot;img-fluid&quot; /&gt;&lt;br&gt;&lt;br&gt;In responsive design there are times when on a mobile screen you want to hide some options with a button to show them, but on a large screen always show these options.&lt;br&gt;&lt;br&gt;For example, a search results page with a bunch of search filters. On a desktop you might want those filters always visible, but on a small screen there might not be enough room and you don't want the search filters at the end of the page because the user would have to scroll all the way to the bottom to find them (they might not know they exist), and you don't want them taking up valuable room at the top of the page.&lt;br&gt;&lt;br&gt;In these cases you want the user to see that filters are available at the top of the small screen page, and give them the option to show these filters with a button.&lt;br&gt;&lt;br&gt;You can do this quite simply in Bootstrap 4 with a few classes.&lt;br&gt;&lt;br&gt;In my example, I'll create a simple two column layout: one for search results and one for search filters. On large screens I want the search filters to be on the right side, but on small screens I want them to appear above the search results and be hidden.&lt;br&gt;&lt;br&gt;So I'll put the search filters column first but use the &quot;order-&quot; classes to re-order them for larger screens (above md).&lt;br&gt;&lt;br&gt;&lt;pre&gt;&amp;lt;div class=&quot;row&quot;&amp;gt;&lt;br&gt;	&amp;lt;div class=&quot;col-md-3 order-md-last&quot;&amp;gt;&lt;br&gt;		&amp;lt;!--Search filters--&amp;gt;&lt;br&gt;	&amp;lt;/div&amp;gt;&lt;br&gt;	&amp;lt;div class=&quot;col-md-9 order-md-first&quot;&amp;gt;&lt;br&gt;		&amp;lt;!--Search results--&amp;gt;&lt;br&gt;	&amp;lt;/div&amp;gt;&lt;br&gt;&amp;lt;/div&amp;gt;&lt;/pre&gt;&lt;br&gt;Next I'll add a button that uses the &quot;collapse&quot; feature and make this visible on small screens but hide on large screens.&lt;br&gt;&lt;br&gt;&lt;pre&gt;&amp;lt;button type=&quot;button&quot; data-toggle=&quot;collapse&quot; data-target=&quot;#filters&quot; class=&quot;d-block d-md-none btn btn-primary btn-block mb-3&quot;&amp;gt;Filters &amp;amp;dtrif;&amp;lt;/button&amp;gt;&lt;/pre&gt;&lt;br&gt;And I'll create a DIV that will house my search filters and make this be shows and hidden by the button collapse, but always shown on large screens.&lt;br&gt;&lt;br&gt;&lt;pre&gt;&amp;lt;div id=&quot;filters&quot; class=&quot;collapse d-md-block&quot;&amp;gt;&lt;br&gt;	&amp;lt;!--Search filters--&amp;gt;&lt;br&gt;&amp;lt;/div&amp;gt;&lt;/pre&gt;&lt;br&gt;See the demo for full example code and see it working.&lt;br&gt;&lt;br&gt;&lt;a href=&quot;/blog/uploads/att950_filters.html&quot; class=&quot;btn btn-primary&quot; target=&quot;_blank&quot;&gt;Demo&lt;/a&gt;</description>
<comments>https://johna.compoutpost.com/blog/950/responsive-collapsing-search-filters-in-bootstrap-4/#comments</comments>
<pubDate>2018-03-26T12:00:00+10:00</pubDate>
<category>Bootstrap</category>
<category>Responsive Web Design</category>
<image>https://johna.compoutpost.com/blog/uploads/img950_bootstrap-responsive-collapsing-search-filters.jpg</image>
<guid>https://johna.compoutpost.com/blog/950</guid>
</item>
<item>
<title>Yet another enhancement of the simple Pinterest Style Grid Layout jQuery Plugin</title>
<link>https://johna.compoutpost.com/blog/837/yet-another-enhancement-of-the-simple-pinterest-style-grid-layout-jquery-plugin/</link>
<description>&lt;img alt=&quot;Pinterest style grid enhancement&quot; src=&quot;/blog/uploads/img837_pinterest-grid-enhancement.jpg&quot; class=&quot;img-fluid&quot; /&gt;&lt;br&gt;&lt;br&gt;The problem with the &lt;a href=&quot;/blog/828/enhanced-simple-pinterest-style-grid-layout-jquery-plugin/&quot;&gt;last version&lt;/a&gt; of Mediademons Simple jQuery Plugin To Create Pinterest Style Grid Layout - Pinterest Grid was that each item would be added consecutively in the next column or row.&lt;br&gt;&lt;br&gt;If one column had very long items then that column could be much longer than the other columns.&lt;br&gt;&lt;br&gt;A critical feature of this layout for my applications is that items should appear top to bottom in a specific order, often chronological.&lt;br&gt;&lt;br&gt;I've updated the script so that items are added to the shortest column. The result is that items may be placed out of order but they are always placed closest to the top.&lt;br&gt;&lt;br&gt;The updated script is below, and a &lt;a href=&quot;/blog/uploads/attt2227_Bootstrap 101 Template.html&quot; target=&quot;_blank&quot;&gt;demo&lt;/a&gt; is available.&lt;br&gt;&lt;br&gt;&lt;pre&gt;/*&lt;br&gt;	Pinterest Grid Plugin&lt;br&gt;	Copyright 2014 Mediademons&lt;br&gt;	@author smm 16/04/2014&lt;br&gt;		&lt;br&gt;	Modified by John Avis 16/11/2017&lt;br&gt;		&lt;br&gt;	usage:&lt;br&gt;		&lt;br&gt;		$(document).ready(function() {&lt;br&gt;		$('#blog-landing').pinterest_grid({&lt;br&gt;			no_columns: 4&lt;br&gt;		});&lt;br&gt;	});&lt;br&gt;*/&lt;br&gt;; (function ($, window, document, undefined) {&lt;br&gt;	var pluginName = 'pinterest_grid',&lt;br&gt;		defaults = {&lt;br&gt;			padding_x: 10,&lt;br&gt;			padding_y: 10,&lt;br&gt;			no_columns: 4,&lt;br&gt;			margin_bottom: 50,&lt;br&gt;			breakpoints: [&lt;br&gt;				[767, 1],&lt;br&gt;				[991, 2],&lt;br&gt;				[1199, 3]&lt;br&gt;			]&lt;br&gt;		},&lt;br&gt;		columns,&lt;br&gt;		$article,&lt;br&gt;		article_width;&lt;br&gt;&lt;br&gt;	function Plugin(element, options) {&lt;br&gt;		this.element = element;&lt;br&gt;		this.options = $.extend({}, defaults, options);&lt;br&gt;		this._defaults = defaults;&lt;br&gt;		this._name = pluginName;&lt;br&gt;		this.init();&lt;br&gt;	}&lt;br&gt;&lt;br&gt;	Plugin.prototype.init = function () {&lt;br&gt;		var self = this,&lt;br&gt;			resize_finish;&lt;br&gt;&lt;br&gt;		$(this.element).find(&quot;img&quot;).load(function () {&lt;br&gt;			$(window).resize();&lt;br&gt;		});&lt;br&gt;&lt;br&gt;		$(window).resize(function () {&lt;br&gt;			clearTimeout(resize_finish);&lt;br&gt;			resize_finish = setTimeout(function () {&lt;br&gt;				self.make_layout_change(self);&lt;br&gt;			}, 11);&lt;br&gt;		});&lt;br&gt;&lt;br&gt;		self.make_layout_change(self);&lt;br&gt;&lt;br&gt;		setTimeout(function () {&lt;br&gt;			$(window).resize();&lt;br&gt;		}, 500);&lt;br&gt;	};&lt;br&gt;&lt;br&gt;	Plugin.prototype.calculate = function (columns) {&lt;br&gt;		var self = this,&lt;br&gt;			tallest = 0,&lt;br&gt;			row = 0,&lt;br&gt;			$container = $(this.element),&lt;br&gt;			container_width = $container.width();&lt;br&gt;		$article = $(this.element).children();&lt;br&gt;&lt;br&gt;		if (columns === 1) {&lt;br&gt;			article_width = $container.width();&lt;br&gt;		} else {&lt;br&gt;			article_width = ($container.width() - self.options.padding_x * (columns - 1)) / columns;&lt;br&gt;		}&lt;br&gt;&lt;br&gt;		$article.each(function () {&lt;br&gt;			$(this).css('width', article_width);&lt;br&gt;		});&lt;br&gt;&lt;br&gt;		var columnTop = [];&lt;br&gt;		for (var i = 1; i &lt;= columns; i++) {&lt;br&gt;			columnTop[i] = 0;&lt;br&gt;		}&lt;br&gt;&lt;br&gt;		$article.each(function (index) {&lt;br&gt;			var current_column,&lt;br&gt;				left_out = 0,&lt;br&gt;				top = 0,&lt;br&gt;				$this = $(this);&lt;br&gt;&lt;br&gt;			current_column = 0;&lt;br&gt;			var minColumnTop = -1;&lt;br&gt;			for (var i = 1; i &lt;= columns; i++) {&lt;br&gt;				if (minColumnTop == -1 || columnTop[i] &lt; minColumnTop) {&lt;br&gt;					current_column = i;&lt;br&gt;					minColumnTop = columnTop[i];&lt;br&gt;				}&lt;br&gt;			}&lt;br&gt;&lt;br&gt;			top = columnTop[current_column];&lt;br&gt;&lt;br&gt;			columnTop[current_column] += $(this).outerHeight() + self.options.padding_y;&lt;br&gt;&lt;br&gt;			if (columns === 1) {&lt;br&gt;				left_out = 0;&lt;br&gt;			} else {&lt;br&gt;				left_out = ((current_column - 1) % columns) * (article_width + self.options.padding_x);&lt;br&gt;			}&lt;br&gt;&lt;br&gt;			$this.css({&lt;br&gt;				'left': left_out,&lt;br&gt;				'top': top&lt;br&gt;			});&lt;br&gt;		});&lt;br&gt;&lt;br&gt;		var paddingy = this.options.padding_y;&lt;br&gt;		largest = Math.max.apply(Math, columnTop) - paddingy;&lt;br&gt;		$container.css('height', largest + this.options.margin_bottom);&lt;br&gt;	};&lt;br&gt;&lt;br&gt;	Plugin.prototype.make_layout_change = function (_self) {&lt;br&gt;		columns = _self.options.no_columns;&lt;br&gt;&lt;br&gt;		for (var i = 0; i &lt; _self.options.breakpoints.length; i++) {&lt;br&gt;			if ($(window).width() &lt;= _self.options.breakpoints[i][0]) {&lt;br&gt;				columns = _self.options.breakpoints[i][1];&lt;br&gt;				break;&lt;br&gt;			}&lt;br&gt;		}&lt;br&gt;&lt;br&gt;		_self.calculate(columns);&lt;br&gt;	};&lt;br&gt;&lt;br&gt;	$.fn[pluginName] = function (options) {&lt;br&gt;		return this.each(function () {&lt;br&gt;			if (!$.data(this, 'plugin_' + pluginName)) {&lt;br&gt;				$.data(this, 'plugin_' + pluginName,&lt;br&gt;					new Plugin(this, options));&lt;br&gt;			}&lt;br&gt;		});&lt;br&gt;	}&lt;br&gt;&lt;br&gt;})(jQuery, window, document);&lt;/pre&gt;&lt;br&gt;&lt;br&gt;See also &lt;a href=&quot;/blog/799/simple-jquery-plugin-to-create-pinterest-style-grid-layout/&quot;&gt;my first post&lt;/a&gt; about this handy jQuery plugin I originally found on &lt;a href=&quot;http://www.jqueryscript.net/layout/Simple-jQuery-Plugin-To-Create-Pinterest-Style-Grid-Layout-Pinterest-Grid.html&quot; target=&quot;_blank&quot;&gt;www.jqueryscript.net&lt;/a&gt;.</description>
<comments>https://johna.compoutpost.com/blog/837/yet-another-enhancement-of-the-simple-pinterest-style-grid-layout-jquery-plugin/#comments</comments>
<pubDate>2017-11-16T12:00:00+10:00</pubDate>
<category>Jquery/Javascript</category>
<category>Responsive Web Design</category>
<image>https://johna.compoutpost.com/blog/uploads/img837_pinterest-grid-enhancement.jpg</image>
<guid>https://johna.compoutpost.com/blog/837</guid>
</item>
<item>
<title>Enhanced simple Pinterest Style Grid Layout jQuery Plugin</title>
<link>https://johna.compoutpost.com/blog/828/enhanced-simple-pinterest-style-grid-layout-jquery-plugin/</link>
<description>&lt;strong&gt;UPDATE: There's a &lt;a href=&quot;/blog/837/yet-another-enhancement-of-the-simple-pinterest-style-grid-layout-jquery-plugin/&quot;&gt;new version&lt;/a&gt; available of this script available now that puts content in the shortest column rather than just in the next row/column position.&lt;/strong&gt;&lt;br&gt;&lt;br&gt;In response to a request, I have made some improvements to the modified version of Mediademons &lt;a href=&quot;http://www.jqueryscript.net/layout/Simple-jQuery-Plugin-To-Create-Pinterest-Style-Grid-Layout-Pinterest-Grid.html&quot; target=&quot;_blank&quot;&gt;Simple jQuery Plugin To Create Pinterest Style Grid Layout - Pinterest Grid&lt;/a&gt;.&lt;br&gt;&lt;br&gt;This original script had a few bugs which I provided fixes for. See my previous post, &lt;a href=&quot;/blog/799/simple-jquery-plugin-to-create-pinterest-style-grid-layout/&quot;&gt; Simple jQuery Plugin To Create Pinterest Style Grid Layout&lt;/a&gt; for more details.&lt;br&gt;&lt;br&gt;Reader Maxim Usik asked to be able to have more than one breakpoint, so that it might have 3 columns on larger screens, 2 columns on a tablet, and 1 column on a mobile phone.&lt;br&gt;&lt;br&gt;I have made some changes to the script and you can now specify the number of columns at any number of breakpoints.&lt;br&gt;&lt;br&gt;The new option is called &quot;breakpoints&quot; and you pass it an array of values, for example:&lt;br&gt;&lt;br&gt;&lt;pre&gt;breakpoints: [  [ 767, 1 ], [ 991, 2 ], [ 1199, 3 ] ]&lt;/pre&gt;&lt;br&gt;For each breakpoint, the first value is the maximum width, and the second value is the number of columns.&lt;br&gt;&lt;br&gt;The default value for this option matches Bootstrap 3.x breakpoints.&lt;br&gt;&lt;br&gt;Also in this update script is small a fix for adjusting the screen as images load.&lt;br&gt;&lt;br&gt;Here is a &lt;a href=&quot;/blog/uploads/att828_pinterest-style-demo.html&quot; target=&quot;_blank&quot;&gt;demo&lt;/a&gt; using Bootstrap 3.x.&lt;br&gt;&lt;br&gt;And here is the updated script.&lt;br&gt;&lt;br&gt;&lt;pre&gt;/*&lt;br&gt;	Pinterest Grid Plugin&lt;br&gt;	Copyright 2014 Mediademons&lt;br&gt;	@author smm 16/04/2014&lt;br&gt;&lt;br&gt;	Modified by John Avis 13/04/2017&lt;br&gt;&lt;br&gt;	usage:&lt;br&gt;&lt;br&gt;		$(document).ready(function() {&lt;br&gt;		$('#blog-landing').pinterest_grid({&lt;br&gt;			no_columns: 4&lt;br&gt;		});&lt;br&gt;	});&lt;br&gt;*/&lt;br&gt;; (function ($, window, document, undefined) {&lt;br&gt;	var pluginName = 'pinterest_grid',&lt;br&gt;		defaults = {&lt;br&gt;			padding_x: 10,&lt;br&gt;			padding_y: 10,&lt;br&gt;			no_columns: 4,&lt;br&gt;			margin_bottom: 50,&lt;br&gt;			breakpoints: [&lt;br&gt;				[ 767, 1 ],&lt;br&gt;				[ 991, 2 ],&lt;br&gt;				[ 1199, 3 ]&lt;br&gt;			]&lt;br&gt;		},&lt;br&gt;		columns,&lt;br&gt;		$article,&lt;br&gt;		article_width;&lt;br&gt;&lt;br&gt;	function Plugin(element, options) {&lt;br&gt;		this.element = element;&lt;br&gt;		this.options = $.extend({}, defaults, options);&lt;br&gt;		this._defaults = defaults;&lt;br&gt;		this._name = pluginName;&lt;br&gt;		this.init();&lt;br&gt;	}&lt;br&gt;&lt;br&gt;	Plugin.prototype.init = function () {&lt;br&gt;		var self = this,&lt;br&gt;			resize_finish;&lt;br&gt;&lt;br&gt;		$(this.element).find(&quot;img&quot;).load(function () {&lt;br&gt;			$(window).resize();&lt;br&gt;		});&lt;br&gt;&lt;br&gt;		$(window).resize(function () {&lt;br&gt;			clearTimeout(resize_finish);&lt;br&gt;			resize_finish = setTimeout(function () {&lt;br&gt;				self.make_layout_change(self);&lt;br&gt;			}, 11);&lt;br&gt;		});&lt;br&gt;&lt;br&gt;		self.make_layout_change(self);&lt;br&gt;&lt;br&gt;		setTimeout(function () {&lt;br&gt;			$(window).resize();&lt;br&gt;		}, 500);&lt;br&gt;	};&lt;br&gt;&lt;br&gt;	Plugin.prototype.calculate = function (columns) {&lt;br&gt;		var self = this,&lt;br&gt;		tallest = 0,&lt;br&gt;		row = 0,&lt;br&gt;		$container = $(this.element),&lt;br&gt;			container_width = $container.width();&lt;br&gt;		$article = $(this.element).children();&lt;br&gt;&lt;br&gt;		if (columns === 1) {&lt;br&gt;			article_width = $container.width();&lt;br&gt;		} else {&lt;br&gt;			article_width = ($container.width() - self.options.padding_x * (columns - 1)) / columns;&lt;br&gt;		}&lt;br&gt;&lt;br&gt;		$article.each(function() {&lt;br&gt;			$(this).css('width', article_width);&lt;br&gt;		});&lt;br&gt;&lt;br&gt;		$article.each(function (index) {&lt;br&gt;			var current_column,&lt;br&gt;				left_out = 0,&lt;br&gt;				top = 0,&lt;br&gt;				$this = $(this),&lt;br&gt;				prevAll = $this.prevAll(),&lt;br&gt;				tallest = 0;&lt;br&gt;&lt;br&gt;			if (columns !== 1) {&lt;br&gt;				current_column = (index % columns);&lt;br&gt;			} else {&lt;br&gt;				current_column = 0;&lt;br&gt;			}&lt;br&gt;&lt;br&gt;			for (var t = 0; t &lt; columns; t++) {&lt;br&gt;				$this.removeClass('c' + t);&lt;br&gt;			}&lt;br&gt;&lt;br&gt;			if (index % columns === 0) {&lt;br&gt;				row++;&lt;br&gt;			}&lt;br&gt;&lt;br&gt;			$this.addClass('c' + current_column);&lt;br&gt;			$this.addClass('r' + row);&lt;br&gt;&lt;br&gt;			prevAll.each(function (index) {&lt;br&gt;				if ($(this).hasClass('c' + current_column)) {&lt;br&gt;					top += $(this).outerHeight() + self.options.padding_y;&lt;br&gt;				}&lt;br&gt;			});&lt;br&gt;&lt;br&gt;			if (columns === 1) {&lt;br&gt;				left_out = 0;&lt;br&gt;			} else {&lt;br&gt;				left_out = (index % columns) * (article_width + self.options.padding_x);&lt;br&gt;			}&lt;br&gt;&lt;br&gt;			$this.css({&lt;br&gt;				'left': left_out,&lt;br&gt;				'top': top&lt;br&gt;			});&lt;br&gt;		});&lt;br&gt;&lt;br&gt;		this.tallest($container);&lt;br&gt;	};&lt;br&gt;&lt;br&gt;	Plugin.prototype.tallest = function (_container) {&lt;br&gt;		var column_heights = [],&lt;br&gt;			largest = 0;&lt;br&gt;&lt;br&gt;		var paddingy = this.options.padding_y;&lt;br&gt;&lt;br&gt;		for (var z = 0; z &lt; columns; z++) {&lt;br&gt;			var temp_height = 0;&lt;br&gt;			_container.find('.c' + z).each(function () {&lt;br&gt;				temp_height += $(this).outerHeight() + paddingy;&lt;br&gt;			});&lt;br&gt;			column_heights[z] = temp_height;&lt;br&gt;		}&lt;br&gt;&lt;br&gt;		largest = Math.max.apply(Math, column_heights) - paddingy;&lt;br&gt;		_container.css('height', largest + this.options.margin_bottom);&lt;br&gt;	};&lt;br&gt;&lt;br&gt;	Plugin.prototype.make_layout_change = function (_self) {&lt;br&gt;		columns = _self.options.no_columns;&lt;br&gt;&lt;br&gt;		for (var i = 0; i &lt; _self.options.breakpoints.length; i++) {&lt;br&gt;			if ($(window).width() &lt;= _self.options.breakpoints[i][0]) {&lt;br&gt;				columns = _self.options.breakpoints[i][1];&lt;br&gt;				break;&lt;br&gt;			}&lt;br&gt;		}&lt;br&gt;&lt;br&gt;		_self.calculate(columns);&lt;br&gt;	};&lt;br&gt;&lt;br&gt;	$.fn[pluginName] = function (options) {&lt;br&gt;		return this.each(function () {&lt;br&gt;			if (!$.data(this, 'plugin_' + pluginName)) {&lt;br&gt;				$.data(this, 'plugin_' + pluginName,&lt;br&gt;				new Plugin(this, options));&lt;br&gt;			}&lt;br&gt;		});&lt;br&gt;	}&lt;br&gt;&lt;br&gt;})(jQuery, window, document);&lt;/pre&gt;</description>
<comments>https://johna.compoutpost.com/blog/828/enhanced-simple-pinterest-style-grid-layout-jquery-plugin/#comments</comments>
<pubDate>2017-04-13T12:00:00+10:00</pubDate>
<category>Jquery/Javascript</category>
<category>Responsive Web Design</category>
<guid>https://johna.compoutpost.com/blog/828</guid>
</item>
<item>
<title>Simple jQuery Plugin To Create Pinterest Style Grid Layout</title>
<link>https://johna.compoutpost.com/blog/799/simple-jquery-plugin-to-create-pinterest-style-grid-layout/</link>
<description>When I was looking for an alternative to &lt;a href=&quot;http://masonry.desandro.com/&quot; target=&quot;_blank&quot;&gt;Masonry&lt;/a&gt; to produce a responsive Pinterest style grid that was a lot simpler and lighter weight I came across this jQuery plugin on &lt;a href=&quot;http://www.jqueryscript.net/layout/Simple-jQuery-Plugin-To-Create-Pinterest-Style-Grid-Layout-Pinterest-Grid.html&quot; target=&quot;_blank&quot;&gt;www.jqueryscript.net&lt;/a&gt; that is very simple and works well.&lt;br&gt;&lt;br&gt;However, It has a few issues which I needed to fix before I could use it.&lt;br&gt;&lt;br&gt;1. The columns do not take up the full width of the container because the width calculation includes horizontal margin on all columns. It should exclude the margin on the final column.&lt;br&gt;&lt;br&gt;2. The height calculation is inaccurate as it does not include vertical padding on every element. I needs to include padding for each element except the last one.&lt;br&gt;&lt;br&gt;3. The function that runs to calculate and adjust sizes calls the window resize event handler every time it runs, which is not necessary, and results in the resize event running constantly. It is possible this was intended to handle loading of images, which effects the size calculation, which I deal with in issue 4.&lt;br&gt;&lt;br&gt;4. If images are not loaded when the script runs then it can't calculate the height required correctly. To accommodate this, I run the resize event each time an image is loaded within the container.&lt;br&gt;&lt;br&gt;Here's the final code. See the page on &lt;a href=&quot;http://www.jqueryscript.net/layout/Simple-jQuery-Plugin-To-Create-Pinterest-Style-Grid-Layout-Pinterest-Grid.html&quot; target=&quot;_blank&quot;&gt;www.jqueryscript.net&lt;/a&gt; for instructions on how to use it.&lt;br&gt;&lt;br&gt;&lt;b&gt;UPDATE 13 April 2017:&lt;/b&gt; I've made some further improvements and fixes to this script. The new script allows you to create multiple breakpoints each with a specific number of columns. See my new post, &lt;a href=&quot;/blog/828/enhanced-simple-pinterest-style-grid-layout-jquery-plugin/&quot;&gt;Enhanced simple Pinterest Style Grid Layout jQuery Plugin&lt;/a&gt;.&lt;br&gt;&lt;br&gt;&lt;b&gt;UPDATE 16 Nov 2017:&lt;/b&gt; There's a &lt;a href=&quot;/blog/837/yet-another-enhancement-of-the-simple-pinterest-style-grid-layout-jquery-plugin/&quot;&gt;new version&lt;/a&gt; available of this script available now that puts content in the shortest column rather than just in the next row/column position.&lt;br&gt;&lt;br&gt;Note that the comments in the code show changes I made.&lt;br&gt;&lt;br&gt;&lt;pre&gt; /*&lt;br&gt;    Pinterest Grid Plugin&lt;br&gt;    Copyright 2014 Mediademons&lt;br&gt;    @author smm 16/04/2014&lt;br&gt;&lt;br&gt;    usage:&lt;br&gt;&lt;br&gt;     $(document).ready(function() {&lt;br&gt;        $('#blog-landing').pinterest_grid({&lt;br&gt;            no_columns: 4&lt;br&gt;        });&lt;br&gt;    });&lt;br&gt;*/&lt;br&gt;; (function ($, window, document, undefined) {&lt;br&gt;	var pluginName = 'pinterest_grid',&lt;br&gt;        defaults = {&lt;br&gt;        	padding_x: 10,&lt;br&gt;        	padding_y: 10,&lt;br&gt;        	no_columns: 3,&lt;br&gt;        	margin_bottom: 50,&lt;br&gt;        	single_column_breakpoint: 700&lt;br&gt;        },&lt;br&gt;        columns,&lt;br&gt;        $article,&lt;br&gt;        article_width;&lt;br&gt;&lt;br&gt;	function Plugin(element, options) {&lt;br&gt;		this.element = element;&lt;br&gt;		this.options = $.extend({}, defaults, options);&lt;br&gt;		this._defaults = defaults;&lt;br&gt;		this._name = pluginName;&lt;br&gt;		this.init();&lt;br&gt;	}&lt;br&gt;&lt;br&gt;	Plugin.prototype.init = function () {&lt;br&gt;		var self = this,&lt;br&gt;            resize_finish;&lt;br&gt;&lt;br&gt;		$(&quot;.blog-landing img&quot;).load(function () {&lt;br&gt;			$(window).resize();&lt;br&gt;		});&lt;br&gt;&lt;br&gt;		$(window).resize(function () {&lt;br&gt;			clearTimeout(resize_finish);&lt;br&gt;			resize_finish = setTimeout(function () {&lt;br&gt;				self.make_layout_change(self);&lt;br&gt;			}, 11);&lt;br&gt;		});&lt;br&gt;&lt;br&gt;		self.make_layout_change(self);&lt;br&gt;&lt;br&gt;		setTimeout(function () {&lt;br&gt;			$(window).resize();&lt;br&gt;		}, 500);&lt;br&gt;	};&lt;br&gt;&lt;br&gt;	Plugin.prototype.calculate = function (single_column_mode) {&lt;br&gt;		var self = this,&lt;br&gt;            tallest = 0,&lt;br&gt;            row = 0,&lt;br&gt;            $container = $(this.element),&lt;br&gt;            container_width = $container.width();&lt;br&gt;		$article = $(this.element).children();&lt;br&gt;&lt;br&gt;		if (single_column_mode === true) {&lt;br&gt;			article_width = $container.width(); // - self.options.padding_x;&lt;br&gt;		} else {&lt;br&gt;			//article_width = ($container.width() - self.options.padding_x * self.options.no_columns) / self.options.no_columns;&lt;br&gt;			article_width = ($container.width() - self.options.padding_x * (self.options.no_columns - 1)) / self.options.no_columns;&lt;br&gt;		}&lt;br&gt;&lt;br&gt;		$article.each(function () {&lt;br&gt;			$(this).css('width', article_width);&lt;br&gt;		});&lt;br&gt;&lt;br&gt;		columns = self.options.no_columns;&lt;br&gt;&lt;br&gt;		$article.each(function (index) {&lt;br&gt;			var current_column,&lt;br&gt;                left_out = 0,&lt;br&gt;                top = 0,&lt;br&gt;                $this = $(this),&lt;br&gt;                prevAll = $this.prevAll(),&lt;br&gt;                tallest = 0;&lt;br&gt;&lt;br&gt;			if (single_column_mode === false) {&lt;br&gt;				current_column = (index % columns);&lt;br&gt;			} else {&lt;br&gt;				current_column = 0;&lt;br&gt;			}&lt;br&gt;&lt;br&gt;			for (var t = 0; t &lt; columns; t++) {&lt;br&gt;				$this.removeClass('c' + t);&lt;br&gt;			}&lt;br&gt;&lt;br&gt;			if (index % columns === 0) {&lt;br&gt;				row++;&lt;br&gt;			}&lt;br&gt;&lt;br&gt;			$this.addClass('c' + current_column);&lt;br&gt;			$this.addClass('r' + row);&lt;br&gt;&lt;br&gt;			prevAll.each(function (index) {&lt;br&gt;				if ($(this).hasClass('c' + current_column)) {&lt;br&gt;					top += $(this).outerHeight() + self.options.padding_y;&lt;br&gt;				}&lt;br&gt;			});&lt;br&gt;&lt;br&gt;			if (single_column_mode === true) {&lt;br&gt;				left_out = 0;&lt;br&gt;			} else {&lt;br&gt;				left_out = (index % columns) * (article_width + self.options.padding_x);&lt;br&gt;			}&lt;br&gt;&lt;br&gt;			$this.css({&lt;br&gt;				'left': left_out,&lt;br&gt;				'top': top&lt;br&gt;			});&lt;br&gt;		});&lt;br&gt;&lt;br&gt;		this.tallest($container);&lt;br&gt;		//$(window).resize();&lt;br&gt;	};&lt;br&gt;&lt;br&gt;	Plugin.prototype.tallest = function (_container) {&lt;br&gt;		var column_heights = [],&lt;br&gt;            largest = 0;&lt;br&gt;&lt;br&gt;		var paddingy = this.options.padding_y;&lt;br&gt;&lt;br&gt;		for (var z = 0; z &lt; columns; z++) {&lt;br&gt;			var temp_height = 0;&lt;br&gt;			_container.find('.c' + z).each(function () {&lt;br&gt;				//temp_height += $(this).outerHeight();&lt;br&gt;				temp_height += $(this).outerHeight() + paddingy;&lt;br&gt;			});&lt;br&gt;			column_heights[z] = temp_height;&lt;br&gt;		}&lt;br&gt;&lt;br&gt;		//largest = Math.max.apply(Math, column_heights);&lt;br&gt;		largest = Math.max.apply(Math, column_heights) - paddingy;&lt;br&gt;		//_container.css('height', largest + (this.options.padding_y + this.options.margin_bottom));&lt;br&gt;		_container.css('height', largest + this.options.margin_bottom);&lt;br&gt;	};&lt;br&gt;&lt;br&gt;	Plugin.prototype.make_layout_change = function (_self) {&lt;br&gt;		if ($(window).width() &lt; _self.options.single_column_breakpoint) {&lt;br&gt;			_self.calculate(true);&lt;br&gt;		} else {&lt;br&gt;			_self.calculate(false);&lt;br&gt;		}&lt;br&gt;	};&lt;br&gt;&lt;br&gt;	$.fn[pluginName] = function (options) {&lt;br&gt;		return this.each(function () {&lt;br&gt;			if (!$.data(this, 'plugin_' + pluginName)) {&lt;br&gt;				$.data(this, 'plugin_' + pluginName,&lt;br&gt;                new Plugin(this, options));&lt;br&gt;			}&lt;br&gt;		});&lt;br&gt;	}&lt;br&gt;&lt;br&gt;})(jQuery, window, document);&lt;/pre&gt;&lt;br&gt;&lt;br&gt;It's also easy to change the number of columns when it changes to &quot;single column&quot; mode by changing the Plugin.prototype.calculate method. Here's what the first part of this method should be changed to (comments show changes):&lt;br&gt;&lt;br&gt;&lt;pre&gt;Plugin.prototype.calculate = function (single_column_mode) {&lt;br&gt;	var self = this,&lt;br&gt;	tallest = 0,&lt;br&gt;	row = 0,&lt;br&gt;	$container = $(this.element),&lt;br&gt;		container_width = $container.width();&lt;br&gt;	$article = $(this.element).children();&lt;br&gt;&lt;br&gt;	//these next lines are new&lt;br&gt;	if (single_column_mode === true) {&lt;br&gt;		columns = 2;&lt;br&gt;		single_column_mode = false;&lt;br&gt;	}&lt;br&gt;	else {&lt;br&gt;		columns = self.options.no_columns;&lt;br&gt;	}&lt;br&gt;&lt;br&gt;	if(single_column_mode === true) {&lt;br&gt;		article_width = $container.width(); // - self.options.padding_x;&lt;br&gt;	} else {&lt;br&gt;		//this next line has been changed&lt;br&gt;		article_width = ($container.width() - self.options.padding_x * (columns - 1)) / columns;&lt;br&gt;	}&lt;br&gt;&lt;br&gt;	$article.each(function() {&lt;br&gt;		$(this).css('width', article_width);&lt;br&gt;	});&lt;br&gt;&lt;br&gt;	//this next line should be removed&lt;br&gt;	//columns = self.options.no_columns;&lt;/pre&gt;</description>
<comments>https://johna.compoutpost.com/blog/799/simple-jquery-plugin-to-create-pinterest-style-grid-layout/#comments</comments>
<pubDate>2016-03-09T12:00:00+10:00</pubDate>
<category>Jquery/Javascript</category>
<category>Responsive Web Design</category>
<guid>https://johna.compoutpost.com/blog/799</guid>
</item>
<item>
<title>My blog updated to Bootstrap 3</title>
<link>https://johna.compoutpost.com/blog/779/my-blog-updated-to-bootstrap-3/</link>
<description>As much as I thought my simple &lt;a href=&quot;/blog/722/cross-browser-responsive-design-without-media-queries/&quot;&gt;JavaScript solution for responsive web design without media queries&lt;/a&gt; was a good idea (and still has a place), I have updated my blog to using the &lt;a href=&quot;http://getbootstrap.com/&quot; target=&quot;_blank&quot;&gt;Bootstrap 3 framework&lt;/a&gt;.&lt;br&gt;&lt;br&gt;The main reason for the update was that I wanted to modernise the blog home page to show a timeline of posts rather than the latest post. This has SEO benefits and presumably most people don't go to the home page but instead come to a specific post either from a search engine or from an email or social share. If they do go to the home page they get an overview of all recent posts now.&lt;br&gt;&lt;br&gt;For the timeline styling I found an excellent solution, &lt;a href=&quot;http://blog.templatemonster.com/2014/04/23/tutorial-build-vertical-timeline-archives-page-using-bootstrap/&quot; target=&quot;_blank&quot;&gt;Build a Vertical Timeline Archives Page Using Bootstrap&lt;/a&gt;, that was simple to implement.&lt;br&gt;&lt;br&gt;&lt;img alt=&quot;Vertical timeline&quot; src=&quot;/blog/uploads/img779_2014.04.23-900x538.jpg&quot; class=&quot;img-responsive&quot; /&gt;&lt;br&gt;&lt;br&gt;I modified it slightly by removing the colours from the timeline CSS and instead adding the Bootstrap &quot;bg-&quot; classes to apply colour. That way if I change the Bootstrap colour scheme I don't also have to change the timeline CSS.&lt;br&gt;&lt;br&gt;As part of the upgrade I have also improved the site navigation and made it easier to browse related posts for something of interest rather than having to read through complete posts one by one.&lt;br&gt;&lt;br&gt;I love the way that Bootstrap gives me, a programmer with little design ability, the ability to focus on back end development and have an attractive and professional looking front end up and running with little to no effort. I know that it then looks like every other Bootstrap site but a blog is (hopefully) more about content so as long as the front end works and doesn't look unattractive then no problem, right?</description>
<comments>https://johna.compoutpost.com/blog/779/my-blog-updated-to-bootstrap-3/#comments</comments>
<pubDate>2015-07-21T12:00:00+10:00</pubDate>
<category>Responsive Web Design</category>
<guid>https://johna.compoutpost.com/blog/779</guid>
</item>
<item>
<title>My blog updated to responsive design</title>
<link>https://johna.compoutpost.com/blog/725/my-blog-updated-to-responsive-design/</link>
<description>For too many years my own blog has been out-dated, still with its' decade old HTML 3.2 markup. I decided to update it and put into action my responsive design techniques.&lt;br&gt;&lt;br&gt;My intention was to make the layout as responsive as possible with just CSS floats, without JavaScript, and supporting as many browsers as possible, including right back to IE6. Then if the browser window size changed beyond what my layout was intended for, either smaller or larger, then certain elements would be show, hidden or moved.&lt;br&gt;&lt;br&gt;The content area of my blog was designed to always be 600 pixels wide, unless the browser window fell below 650 pixels wide (600 pixels plus 25 pixel margins either side). Once below this point the content area should change to auto width to fill the browser window (with margins). Then I have another breakpoint to reduce the horizontal margins to only 10px when the display width falls below 620 pixels.&lt;br&gt;&lt;br&gt;I also wanted anyone browsing full size on a 1920 by 1080 pixel monitor to make more use of all the available space. So I decided to have the comments element positioned to the right of the main content area at display widths above 1890 pixels.&lt;br&gt;&lt;br&gt;&lt;a href=&quot;/blog/uploads/img725_layout.jpg&quot;&gt;&lt;img alt=&quot;Planned layout&quot; src=&quot;/blog/thumb/img725_layout_lg.jpg&quot; class=&quot;img-fluid&quot; /&gt;&lt;/a&gt;&lt;br&gt;&lt;br&gt;To accomplish the changes at the maximum width of 650 pixels and the minimum width of 1890 pixels I used my &lt;a href=&quot;/blog/default.asp?id=722&quot;&gt;Cross-browser responsive design without media queries&lt;/a&gt; jQuery to apply different classes to the BODY element at these breakpoints.&lt;br&gt;&lt;br&gt;This type of design is a simple way of doing effective responsive design without resorting to a more complex grid based layout. Basically my design uses fixed width building blocks which only become fluid when the browser width falls below the standard width of the main content area. To sum up here are some tips:&lt;br&gt;&lt;br&gt;* Create fixed width elements&lt;br&gt;* Use CSS floats to position these items&lt;br&gt;* Add a media query (or equivalent) to change to fluid widths once the width falls below the width of your main content&lt;br&gt;&lt;br&gt;Also in use is my &lt;a href=&quot;/blog/default.asp?id=723&quot;&gt;Image resizing solution for Responsive Design&lt;/a&gt; which uses jQuery and server-side image resizing to request the correct sized image from the server for the current browser window size.</description>
<comments>https://johna.compoutpost.com/blog/725/my-blog-updated-to-responsive-design/#comments</comments>
<pubDate>2013-06-21T12:00:00+10:00</pubDate>
<category>Responsive Web Design</category>
<image>https://johna.compoutpost.com/blog/uploads/img725_layout.jpg</image>
<guid>https://johna.compoutpost.com/blog/725</guid>
</item>
<item>
<title>Image resizing solution for Responsive Design</title>
<link>https://johna.compoutpost.com/blog/723/image-resizing-solution-for-responsive-design/</link>
<description>Following on from my previous article on &lt;a href=&quot;/blog/default.asp?id=722&quot;&gt;responsive design without media queries&lt;/a&gt;, I have been looking for how to handle the problem of image size and display in responsive design.&lt;br&gt;&lt;br&gt;The problems are: (a) how do you provide the correct pixel size image; and (b) how do you prevent loading of invisible images.&lt;br&gt;&lt;br&gt;The solution I present here handles these problems with jQuery and a server-side script to handle image resizing. The idea is that you add the highest resolution image your design will need, then resize it server-side as needed.&lt;br&gt;&lt;br&gt;&lt;b&gt;Note: this will not be a simple to implement solution for many people. It requires server-side image resizing and a little knowledge of JavaScript/jQuery to suit your needs.&lt;/b&gt;&lt;br&gt;&lt;br&gt;Implementation requires that all images have a width, whether it be in pixels or percentage, and that the responsive image tags be replaced with something like the following:&lt;br&gt;&lt;br&gt;&lt;pre&gt;&amp;lt;img alt=&quot;Sample&quot; data-original=&quot;http://mysite.com/coffee5.jpg&quot; src=&quot;placeholder.gif&quot; /&amp;gt;&lt;/pre&gt;&lt;br&gt;&lt;br&gt;The &lt;b&gt;src&lt;/b&gt; is replaced with a placeholder image that should be used for all responsive image tags, so is only loaded once. It can be a 1 by 1 pixel image.&lt;br&gt;&lt;br&gt;The &lt;b&gt;data-original&lt;/b&gt; attribute is added and has the URL of your server-side image resizing service and the name of the image. The jQuery script will automatically append the required width to this URL.&lt;br&gt;&lt;br&gt;If JavaScript is disabled it is possible to have a fallback image, for example:&lt;br&gt;&lt;br&gt;&lt;pre&gt;&amp;lt;span class=&quot;fallback&quot;&amp;gt;&amp;lt;img alt=&quot;Sample&quot; data-original=&quot;http://mysite.com/coffee5.jpg&quot; src=&quot;placeholder.gif&quot; /&amp;gt;&amp;lt;/span&amp;gt;&lt;br&gt;&amp;lt;noscript&amp;gt;&amp;lt;img alt=&quot;Sample&quot; src=&quot;http://mysite.com/coffee5.jpg&quot; /&amp;gt;&amp;lt;/noscript&amp;gt;&lt;/pre&gt;&lt;br&gt;&lt;br&gt;The &lt;b&gt;span&lt;/b&gt; is added around the image, and the &lt;b&gt;fallback&lt;/b&gt; class is set to &lt;i&gt;display:none&lt;/i&gt; so as to hide the image initially. If JavaScript is enabled then &lt;i&gt;display:inline&lt;/i&gt; can be set on all items with the &lt;b&gt;fallback&lt;/b&gt; class. This is required if the image is not set to display using media queries or jQuery, the script will be able to determine if the image is visible or not.&lt;br&gt;&lt;br&gt;Here's the jQuery plugin to handle loading of the correct size images, if visible:&lt;br&gt;&lt;br&gt;&lt;pre&gt;(function ($) {&lt;br&gt;	$.fn.responsiveImages = function () {&lt;br&gt;		return this.each(function () {&lt;br&gt;			if ($(this).is(&quot;:visible&quot;)) {&lt;br&gt;				$(this).attr(&quot;src&quot;, $(this).attr(&quot;data-original&quot;) + &quot;?w=&quot; + $(this).width());&lt;br&gt;			}&lt;br&gt;		});&lt;br&gt;	};&lt;br&gt;})(jQuery);&lt;br&gt;&lt;br&gt;$(function () {&lt;br&gt;	$(&quot;.fallback&quot;).css(&quot;display&quot;, &quot;inline&quot;);&lt;br&gt;	$(&quot;#article img&quot;).responsiveImages();&lt;br&gt;&lt;br&gt;	//Optional reload new images on resize&lt;br&gt;	var resizeTimer;&lt;br&gt;	$(window).resize(function () {&lt;br&gt;		if (resizeTimer !== false) clearTimeout(resizeTimer);&lt;br&gt;		resizeTimer = setTimeout(function () {&lt;br&gt;			$(&quot;#article img&quot;).responsiveImages();&lt;br&gt;		}, 500);&lt;br&gt;	});&lt;br&gt;});&lt;/pre&gt;&lt;br&gt;&lt;br&gt;There's some optional code in there that will also get new resized images if the window is resized or changed from portrait to landscape, etc. I wouldn't recommend using this if you use proportional size images where there could be many, many different pixel sizes based on the browser window size. If you have only a few breakpoints and fixed pixel widths for the images then it is viable to use this.&lt;br&gt;&lt;br&gt;Here's a sample that also uses my jQuery responsive design without media queries script.&lt;br&gt;&lt;br&gt;&lt;a href=&quot;/blog/uploads/att723_test.htm&quot;&gt;Example&lt;/a&gt;</description>
<comments>https://johna.compoutpost.com/blog/723/image-resizing-solution-for-responsive-design/#comments</comments>
<pubDate>2013-06-15T12:00:00+10:00</pubDate>
<category>Responsive Web Design</category>
<guid>https://johna.compoutpost.com/blog/723</guid>
</item>
<item>
<title>Cross-browser responsive design without media queries</title>
<link>https://johna.compoutpost.com/blog/722/cross-browser-responsive-design-without-media-queries/</link>
<description>&lt;h2&gt;...Or an alternative to media queries for responsive design&lt;/h2&gt;&lt;br&gt;I really like the concept of responsive design, and I have read a lot of the positive stuff about it, and also read a lot of the negative too.&lt;br&gt;&lt;br&gt;Despite the negatives, I do think that responsive design is the way of the future (and now), but it seems that it is far from easy to get right.&lt;br&gt;&lt;br&gt;I'm taking my first steps in responsive design now, but one of the first issues I encountered is browser compatibility for CSS3 media queries. The Google Analytics statistics for most of the sites I maintain still show enough users with Internet Explorer 8 that I still need to consider these browsers during development.&lt;br&gt;&lt;br&gt;I have looked at some of the well-known fixes but the idea of requesting my CSS files by AJAX and parsing them doesn't sound too efficient, even though it will only happen with IE8 and below.&lt;br&gt;&lt;br&gt;An alternative is to use JavaScript or jQuery to handle the change of display size for all browsers, and I put something together quickly to do this. As the experimental work I have done so far has only involved using &quot;max-width&quot;, my jQuery example presented here works only that way.&lt;br&gt;&lt;br&gt;It works simply by applying classes to a specified tag (default is BODY tag). So if you have breakpoints set at 500 pixels and 300 pixels, it will apply no classes at 600 pixels, the 500 pixel class (which you specify) once the display width is less than or equal to 500 pixels, and both the 500 and 300 pixels classes when the display width is less than or equal to 300 pixels. It adjusts classes on document ready and when the browser is resized.&lt;br&gt;&lt;br&gt;Here's the code and a sample (jQuery required):&lt;br&gt;&lt;br&gt;&lt;pre&gt;&amp;lt;script type=&quot;text/javascript&quot;&amp;gt;&lt;br&gt;	(function ($) {&lt;br&gt;	    	jQuery.responsive = function (options) {&lt;br&gt;	    		var settings = $.extend({&lt;br&gt;	    			breakpoints: [],&lt;br&gt;	    			container: &quot;body&quot;&lt;br&gt;	    		}, options);&lt;br&gt;	    		$(window).resize(function () {&lt;br&gt;	    			respond();&lt;br&gt;	    		});&lt;br&gt;	    		respond();&lt;br&gt;	    		function respond() {&lt;br&gt;	    			for (var i = 0; i &lt; settings.breakpoints.length; i++) {&lt;br&gt;	    				if ($(window).width() &lt;= settings.breakpoints[i][0]) {&lt;br&gt;	    					$(settings.container).addClass(settings.breakpoints[i][1]);&lt;br&gt;	    				}&lt;br&gt;	    				else {&lt;br&gt;	    					$(settings.container).removeClass(settings.breakpoints[i][1]);&lt;br&gt;	    				}&lt;br&gt;	    			}&lt;br&gt;	    		};&lt;br&gt;	    	}&lt;br&gt;	})(jQuery);&lt;br&gt;&lt;br&gt;	//Sample usage - adds two breakpoints and applies class to BODY tag&lt;br&gt;	$(function () {&lt;br&gt;		$.responsive({&lt;br&gt;			//array with max-width in pixels, and class to apply&lt;br&gt;			breakpoints: [[980, &quot;mw980&quot;], [480, &quot;mw480&quot;]]&lt;br&gt;			//optional specify container to apply classes to, default is body&lt;br&gt;			//,container: &quot;#wrapper&quot;&lt;br&gt;		});&lt;br&gt;	});&lt;br&gt;&amp;lt;/script&amp;gt;&lt;/pre&gt;&lt;br&gt;I mocked up a couple of samples, one using media queries and my alternative using jQuery:&lt;br&gt;&lt;br&gt;&lt;a href=&quot;/blog/uploads/att722_media-queries.htm&quot; target=&quot;_blank&quot;&gt;Example using media queries&lt;/a&gt;&lt;br&gt;&lt;br&gt;&lt;a href=&quot;/blog/uploads/att722_jquery-alternative.htm&quot; target=&quot;_blank&quot;&gt;Example using jQuery&lt;/a&gt;&lt;br&gt;&lt;br&gt;They should appear and operate identically in all browsers, except IE8 and below where the media queries example will not work as designed.&lt;br&gt;&lt;br&gt;&lt;b&gt;Update:&lt;/b&gt; I have since redesigned my blog using this technique. I also added support for min-width. You can look at the source of this page to see updated code.&lt;br&gt;&lt;br&gt;&lt;b&gt;Update:&lt;/b&gt; I found that one of the disadvantages of using this technique is that the adding of classes does not happen until document ready. This means that there can be a delay in applying the classes which is visible to the user. To solve this problem I suggest adding a second script using native JavaScript to add the classes immediately after the BODY open tag (or whichever tag has the clases applied). Example (also applied to this website):&lt;br&gt;&lt;br&gt;&lt;pre&gt;var container = &quot;body&quot;; //must be ID&lt;br&gt;var breakpoints = [&lt;br&gt;	[&quot;max-width&quot;, 650, &quot;max650&quot;],&lt;br&gt;	[&quot;min-width&quot;, 986, &quot;min986&quot;]&lt;br&gt;];&lt;br&gt;for (var i = 0; i &lt; breakpoints.length; i++) {&lt;br&gt;	if (breakpoints[i][0] == &quot;max-width&quot;) {&lt;br&gt;		if (window.innerWidth &lt;= breakpoints[i][1]) {&lt;br&gt;			document.getElementById(container).className = breakpoints[i][2];&lt;br&gt;		}&lt;br&gt;	}&lt;br&gt;	else if (breakpoints[i][0] == &quot;min-width&quot;) {&lt;br&gt;		if (window.innerWidth &gt;= breakpoints[i][1]) {&lt;br&gt;			document.getElementById(container).className = breakpoints[i][2];&lt;br&gt;		}&lt;br&gt;	}&lt;br&gt;}&lt;/pre&gt;&lt;br&gt;&lt;br&gt;I've actually created some ASP.NET server controls to handle this in some of the projects I am working on. Let me know if you're interested in seeing that.&lt;br&gt;&lt;br&gt;&lt;b&gt;Update:&lt;/b&gt;&lt;br&gt;&lt;br&gt;I have created a pure JavaScript version of the cross-browser responsive media query alternative code. This version should be placed immediately after the opening tag for the element that classes are to be applied. The id of that element and the breakpoints need to be adjusted to your requirements. Here's an example:&lt;br&gt;&lt;br&gt;&lt;pre&gt;&amp;lt;script type=&quot;text/javascript&quot;&amp;gt;&lt;br&gt;	function hasClass(el, cls) {&lt;br&gt;		return el.className.match(new RegExp('(\\s|^)' + cls + '(\\s|$)'));&lt;br&gt;	}&lt;br&gt;	function addClass(el, cls) {&lt;br&gt;		if (!this.hasClass(el, cls)) el.className += &quot; &quot; + cls;&lt;br&gt;	}&lt;br&gt;	function removeClass(el, cls) {&lt;br&gt;		if (hasClass(el, cls)) {&lt;br&gt;			var reg = new RegExp('(\\s|^)' + cls + '(\\s|$)');&lt;br&gt;			el.className = el.className.replace(reg, ' ');&lt;br&gt;		}&lt;br&gt;	}&lt;br&gt;&lt;br&gt;	var addEvent = function (elem, type, eventHandle) {&lt;br&gt;		if (elem == null || elem == undefined) return;&lt;br&gt;		if (elem.addEventListener) {&lt;br&gt;			elem.addEventListener(type, eventHandle, false);&lt;br&gt;		} else if (elem.attachEvent) {&lt;br&gt;			elem.attachEvent(&quot;on&quot; + type, eventHandle);&lt;br&gt;		} else {&lt;br&gt;			elem[&quot;on&quot; + type] = eventHandle;&lt;br&gt;		}&lt;br&gt;	};&lt;br&gt;&lt;br&gt;	function responsive() {&lt;br&gt;		var w = window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth;&lt;br&gt;&lt;br&gt;		for (var i = 0; i &lt; breakpoints.length; i++) {&lt;br&gt;			if (breakpoints[i][0] == &quot;max-width&quot;) {&lt;br&gt;				if (w &lt;= breakpoints[i][1]) {&lt;br&gt;					addClass(document.getElementById(id), breakpoints[i][2]);&lt;br&gt;				}&lt;br&gt;				else {&lt;br&gt;					removeClass(document.getElementById(id), breakpoints[i][2]);&lt;br&gt;				}&lt;br&gt;			}&lt;br&gt;			else if (breakpoints[i][0] == &quot;min-width&quot;) {&lt;br&gt;				if (w &gt;= breakpoints[i][1]) {&lt;br&gt;					addClass(document.getElementById(id), breakpoints[i][2]);&lt;br&gt;				}&lt;br&gt;				else {&lt;br&gt;					removeClass(document.getElementById(id), breakpoints[i][2]);&lt;br&gt;				}&lt;br&gt;			}&lt;br&gt;		}&lt;br&gt;	}&lt;br&gt;&lt;br&gt;	var resizeTimeoutId;&lt;br&gt;&lt;br&gt;	function resized() {&lt;br&gt;		window.clearTimeout(resizeTimeoutId);&lt;br&gt;		resizeTimeoutId = window.setTimeout('responsive();', 10);&lt;br&gt;	}&lt;br&gt;&lt;br&gt;	var id = &quot;body&quot;;&lt;br&gt;	var breakpoints = [[&quot;max-width&quot;, 630, &quot;max630&quot;], [&quot;min-width&quot;, 1890, &quot;min1890&quot;]];&lt;br&gt;&lt;br&gt;	addEvent(window, &quot;resize&quot;, resized);&lt;br&gt;&lt;br&gt;	responsive();&lt;br&gt;&amp;lt;/script&amp;gt;&lt;/pre&gt;</description>
<comments>https://johna.compoutpost.com/blog/722/cross-browser-responsive-design-without-media-queries/#comments</comments>
<pubDate>2013-06-07T12:00:00+10:00</pubDate>
<category>Responsive Web Design</category>
<category>Jquery/Javascript</category>
<guid>https://johna.compoutpost.com/blog/722</guid>
</item>
</channel>
</rss>
