Responsive, square elements with JavaScript/jQuery


A simple idea…

If you’re a designer, it’s pretty natural to want a bunch of squares to line up next to each other.

And if you’re a designer who’s up on responsive design best practices (which we strongly recommend), it’s very natural to want these squares to dynamically resize themselves for different screen widths.

In short, you might want something like this:

This was the look we wanted for our portfolio.

…but not with CSS

As we started to design our portfolio, though, we realized that it’s very difficult—at the time, we thought impossible—to design responsive (that is, percentage-width rather than fixed-width), square elements with straight CSS.

As massively useful as it would be, there’s nothing in the CSS spec for “make this element’s height precisely 100% of its own width.”

The reason is because, as massively useful as it would be, there’s nothing in the CSS spec for “make this element’s height precisely 100% of its own width.” CSS won’t let you use element attributes as variables, and it won’t let you use widths as a reference to set heights (height:100% will always refer to 100% of the height of some other element, never the width of any element). This means that the easy ways to do responsive square elements with CSS won’t work.

What to do

There are at least three ways around this. One (not explored here) is to manually set fixed widths and heights for your squares, and get the responsive functioning you’re looking for by resizing them at a number of different breakpoints.

A second way, which a reader pointed out, is to make creative use of 0 heights and padding; see example, and screenshot of example with nested elements. (Please note that you don’t need to name any elements either “herp” or “derp”; in fact, probably better if you don’t.) This is a good solution, although it leaves all square elements with 0 height, which can cause further complications down the line (if, for example, you wanted to nest backgrounds for a “photo caption” effect; see problematic screenshot).

The third way, which we used, is with JavaScript/jQuery. JavaScript lets you store element properties as variables, which is all we need to set an element’s height equal to its width.

Here’s the code:

The jQuery


// adjustHeight is the function that makes the objects squares
// (by setting each one's height equal to its width)
function adjustHeight() {
	var myWidth = jQuery('.square-element').width();
	var myString = myWidth + 'px';
	jQuery('.square-element').css('height', myString);
	return myHeight;
}

// calls adjustHeight on window load
jQuery(window).load(function() {
	adjustHeight();
});

// calls adjustHeight anytime the browser window is resized
jQuery(window).resize(function() {
	adjustHeight();
});

Note: square-element is the (arbitrary) class name of our squares; you can name your square elements whatever you want.

The CSS



/* Defines the squares' margins and shadows,
and the default three-column layout */
.square-element {
	float: left;
	width: 29.3%;
	height: 300px;
	margin: 9px .85%;
	padding: .85%;
	border: 1px #aaa solid;
	background: #fff;
	box-shadow: 5px 5px 3px #ccc;
}

/* Switching to two-column layout at first responsive breakpoint */
@media (max-width: 790px)
	.square-element {
		width: 43.6%;
		padding: 1.7%;
	}
}

/* Switching to one-column layout at second responsive breakpoint */
@media (max-width: 430px) {
	.square-element {
		width: 92.4%;
		padding: 2.8%;
	}
}

Note: You can do whatever you like here. The styling above is for our portfolio items; they start out in columns of three, then rearrange into columns of two and one at different responsive breakpoints. The widths have allowances for a text-shadow and margins between items.

The result

We’ve shown the result above, with pictures of my old house standing in for whatever other kind of content you might want to add inside the responsive squares. The squares smoothly resize themselves as you resize your browser window, and break into different column configurations at set breakpoints.

Further notes

  • If your jQuery script loads significantly later than your square elements, the elements will start out rectangular, then “flicker” to square. (We’ve left this in place with the example above; reload while viewing that part of the page and you’ll see what we’re talking about.) There are ways to load JavaScript without a flicker.
  • If you’re looking for a good number of responsive square elements to list, we suggest twelve, which is divisible by 2, 3, and 4. This means that your portfolio (or whatever) will keep a rectangular shape in most column configurations.
  • The six elements we listed above are floating, so make sure to wrap them in something that clears the float or you could have problems.

We went ahead and made our portfolio into a (private) plugin, so if you want something very similar, feel free to ask us about it. We may save you some development time.

Finally, please share and comment—we appreciate it!

4 thoughts on “Responsive, square elements with JavaScript/jQuery

    1. Fred Meyer Post author

      Thanks, Gerald! Have confirmed this works. I also did a bit of thinking about the potential drawbacks of this solution. I’ve edited the post content (in “What to do”) accordingly.

      Reply
  1. C975A23

    Thanks for the code! Works like a charm! I only used the jQuery code without the CSS, and already that alone works well just I need! Could be worth posting this on numerous Stackoverflow questions, as I could not find any working solution there (strangely)!

    Reply

Leave a Reply

Your email address will not be published.