Managing Responsive Website Breakpoints Without Cluttering Up Your Stylesheet

By Neal Grosskopf, Software Engineering Director

Published: September 22, 2014

In the past, it’s always felt like I’ve needed to write too many ‘exceptions’ in my CSS when re-styling things for mobile and desktop. For instance, let’s say I have an image on a page that is aligned right with some copy around it:

example1

When the viewport is at a certain size, let’s say I want to unfloat that image and make it 100% wide like so:

example2

I could add a specific class to this image such as .article-image and then in my CSS, unfloat it and make it 100% wide at a certain point, but that doesn’t allow for re-usability. Maybe I want to use that same functionality on another page that doesn’t have articles on it. Or perhaps I want to do the same thing but at a different breakpoint in my stylesheet. Maybe I want to unfloat it but not make it 100% wide.

In the past, my CSS might look like this:

.article-image
{
float: right;
margin: 0px 0px 12px 12px;
}

@media (max-width: 480px) {

	.article-image
	{
	float: none;
	clear: both;
	}

}

Rather than do that, why not use HTML5’s new data-attributes to solve the job to target specific breakpoints?

@media (max-width: 480px) {
	
	[data-unfloat-bp="mobile"]
	{
	float: none;
	clear: both;
	}
	
	[data-fullwidth-bp="mobile"]
	{
	box-sizing: border-box;
	margin-left: 0px;
	margin-right: 0px;
	width: 100%;
	}

}

My final IMG element might look like this:

<img src="image.jpg" class="content-right" data-unfloat-bp="mobile" data-fullwidth-bp="mobile">

So why bother with this, isn’t it exactly like the last example except using data-attributes? The real magic occurs when you start considering other breakpoints. Let’s say I want one image to do this at one breakpoint and another image to do it at another breakpoint on the same page. I can start ‘naming’ the values in my data-attribute to target specific breakpoints.

@media (max-width: 480px) {
	[data-unfloat-bp="mobilelandscape"]	
	...	
	
	[data-fullwidth-bp="mobilelandscape"]
	...
}

@media (max-width: 320px) {
	[data-unfloat-bp="mobileportrait"]
	...	
	
	[data-fullwidth-bp="mobileportrait"]
	...
}

With this, we can now target specific breakpoints directly in our HTML rather than write exceptions each time like so:

<img src="image.jpg" class="content-right" data-unfloat-bp="mobilelandscape" data-fullwidth-bp="mobilelandscape">
<img src="image.jpg" class="content-right" data-unfloat-bp="mobileportrait" data-fullwidth-bp="mobileportrait">

Why Use Data Attributes?

The reason I chose to use data-attributes is an idea I stole from jQuery Mobile. In JQM data-attributes are used to apply theming to elements. I like using them in this case because they allow for different singular values where HTML classes all get grouped together. I find that the grouping can get confusing sometimes as I already have a lot of classes added to an element as it is.

Keeping things ‘DRY’ with SASS

One flaw that can be seen in the above example is that I need to repeat myself for each media query. Since I had duplicating code, a solution for this is to use SASS with a mixin.

@mixin breakpoints($bp)
{
	[data-unfloat-bp="#{$bp}"]
	{
	float: none;
	clear: both;
	}
	
	[data-fullwidth-bp="#{$bp}"]
	{
	box-sizing: border-box;
	margin-left: 0px;
	margin-right: 0px;
	width: 100%;
	}
}

Then in my CSS I do the following:

@media (max-width: 480px) {
	
	@include breakpoints("mobilelandscape");
	
}

@media (max-width: 320px) {

	@include breakpoints("mobileportrait");

}

Other Common Responsive Solutions

After awhile I’ve noticed that I’m re-styling the same things over and over again when switching between breakpoints. When this happens, I build another data-attribute modifier and add it to the SASS mixin.

Here’s a list of things I find myself re-styling frequently:

  • Unfloating elements
  • Making elements 100% wide
  • Hiding elements
  • Showing elements
  • Adding top and bottom spacing to an elements