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:
When the viewport is at a certain size, let’s say I want to unfloat that image and make it 100% wide like so:
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