Learnings from using Sass in large scale projects

Different projects I have worked on used Sass as the pre-compiler of their choice. This post shares some learnings we had while using Sass. There are a couple of great articles on how to use Sass in large scale projects — this one is more of a retrospective. I hope it helps you solving problems if you ever run into them.

I wrote about some of my recent projects and the learnings I had.

Introducing INIT – A Boilerplate Framework for Front-End Projects

INIT is based upon HTML5 Boilerplate and adds more structure for SCSS files, JavaScripts, includes build tasks and a whole lot more.

Today we released INIT, a front-end framework based on Grunt, Bower, Karma and a lot more tools as version 1.0. This marks a special day for Anselm and me, as we worked for a long period to get this project to where it is today.

Over at TNG I wrote a bit about why we need frameworks like these and what the challenges with current tools are:

Generally we start a lot of our projects in kind of the same way. A lot of tasks need to be repeated from one project to another since we tend to set up our development and deployment workflow in similar ways everytime.

Please drop by and read the full article, provide feedback for INIT via GitHub or just tweet about it if you feel like it :)

INIT’s website    INIT on GitHub

Add the <main>-Element to Modernizr 2.6.2

We don’t need this anymore

With Modernizr v2.7.0 we don’t need this work around anymore. Please update to this version if you use <main>.

tl;dr: You can add the new main-element to Modernizr 2.6.2 by using HTML5 Shiv’s window.html5 option to add your own elements to the shiv.


Since I use some bleeding edge stuff in HTML and CSS in actual projects for clients I ran into one particular issue a couple of times lately and I thought I share a little workaround with you.

Modernizr’s current state

Modernizr includes HTML5 Shiv to make HTML5 elements like header, figure and time known and styleable in old IE. Due to development for Modernizr version 3 the current version is Modernizr 2.6.2 which was published nearly a year ago (September 2012) when the main-element wasn’t around yet. Thus the version of HTML5 Shiv does not include a shiv for the main-element.

Today main is part of the HTML5 specification and is implemented in Chrome, Firefox and Safari Nightlies. You can read more about its value especially for semantics and accessibility on MDN and in a recent article at HTML5 Doctor.

The guys behind HTML5 Shiv included the main-element some time ago (you can learn more about the process of including some kind of default styling for the element in another HTML5 Shiv issue (thanks Mathias for the pointer)) and it is available in version 3.6.2. Sadly the latest stable version of Modernizr only includes version 3.6.1 of the shiv and there is no date set for a new release of Modernizr since everyone on the team tries to push version 3 to be out as soon as possible which will them include the new version of the shiv.

The Workaround

Until then we need to work around the missing shiv for the main-element (along with dialog and template).
Luckily it is possible to extend the list of elements HTML5 Shiv operates upon via its html5.elements option that we can use as needed.

First of all we need to create an object html5 on the window object and then add all elements that we want to be shiv’d.

window.html5 = {
  elements: 'abbr article aside audio bdi canvas data datalist details dialog ' +
      'figcaption figure footer header hgroup main mark meter nav output progress ' +
      'section summary template time video'
};

It is useful to take the list from the current version of the shiv to include all elements that need the shiv.

This code needs to be included before Modernizr is actually invoked so it might be useful to place it inline right before you insert Modernizr itself.

There is another way to include only specific elements like for example the main-element after Modernizr is already included:

window.html5.elements = 'main';
window.html5.shivDocument(document); // re-invoke the `shivDocument` method

Conclusion

This method is pretty straightforward and saves you a lot of time debugging or working around the inclusion of the main-element if you use Modernizr anyway.

A Few More Words on Accessible Dialogs/Modals

tl;dr: It’s necessary to keep the focus within a dialog while tabbing through it. The function below is the easiest way to implement this behavior in JavaScript.


When I created CSS Modal I wanted it to be accessible for screen readers and people that only use the keyboard for navigation. Nicholas Zakas has a great post that helped me a lot with making CSS Modal accessible without too much work.

This posts explains a bit about aria roles, how to use tabindex and how you set focus to the element initially and bringing it back where it was before when the modal gets closed.

But there is one thing it misses and which was raised as an issue against CSS Modal: It should be possible to tab through the modal and keep the focus within the modal while it is active. A circular tabbing through a particular area of a page so to speak.

After some research I came up with a straightforward function that does exactly this. Let’s look at how this function is build and how you can use it.

I’ve created a Gist that you can use if you don’t want the walk-through.

Circular Focus

First of all we need to know what the first and the last element of out particular area is that might receive focus while tabbing through. We could give them an ID and find them with document.getElementById.
Let’s assume we don’t know what the content of that area is and we do not have any influence on the given IDs and stuff. This means we need to filter the first and the last tabbable element. There are some elements that are tabbable especially those which are links, user-input fields or have a tabindex attribute on them (from this answer on StackOverflow).

Here is a full list of CSS selectors:

a[href], area[href], input:not([disabled]), select:not([disabled]), textarea:not([disabled]), button:not([disabled]), iframe, object, embed, *[tabindex], *[contenteditable]

This is the list of selectors we need to use to find the first and last tabbable element. So let’s put them into a variable we can use in our function.

var tabbableElements = 'a[href], area[href], input:not([disabled]),' +
	'select:not([disabled]), textarea:not([disabled]),' +
	'button:not([disabled]), iframe, object, embed, *[tabindex],' +
	'*[contenteditable]';

And here is how we find the elements in a given context context:

// First, let's find all tabbable elemets
var allTabbableElements = context.querySelectorAll(tabbableElements);
 
// The first of this list
var firstTabbableElement = allTabbableElements[0];
 
// And the last one
var lastTabbableElement = allTabbableElements[allTabbableElements.length - 1];

A keydown Listener

What we need next is a listener on the last element that will fire when we hit the TAB key on it.
Note: Please remember that IE8 does not support addEventListener, so please use attachEvent where needed.

lastTabbableElement.addEventListener('keydown', function () { /* More magic */ }, false);

The handler for the event listener might look something like that:

var keyCode = event.which || event.keyCode; // Get the current keycode
 
// If it is TAB
if (keyCode === 9) {
 
	// Prevent the default behavior
	if (event.preventDefault) {
		event.preventDefault();
	} else {
		event.returnValue = false;
	}
 
	// Move the focus to the first element that can be tabbed
	firstTabbableElement.focus();
}

So if we reach the end of the element we want to circle in, we just go back to the first tabbable element and focus this. We need to prevent the default behavior – which would be to jump the the next link, out of the element – though.

A Reusable Function

Let’s throw this all together and we get a neat little function that we can call on all elements where we want the focus to stay in.

var tabbableElements = 'a[href], area[href], input:not([disabled]),' +
	'select:not([disabled]), textarea:not([disabled]),' +
	'button:not([disabled]), iframe, object, embed, *[tabindex],' +
	'*[contenteditable]';
 
var keepFocus = function (context) {
	var allTabbableElements = context.querySelectorAll(tabbableElements);
	var firstTabbableElement = allTabbableElements[0];
	var lastTabbableElement = allTabbableElements[allTabbableElements.length - 1];
 
	var keyListener = function (event) {
		var keyCode = event.which || event.keyCode; // Get the current keycode
 
		// If it is TAB
		if (keyCode === 9) {
 
			// Prevent the default behavior
			if (event.preventDefault) {
				event.preventDefault();
			} else {
				event.returnValue = false;
			}
 
			// Move the focus to the first element that can be tabbed
			firstTabbableElement.focus();
		}
	};
 
	lastTabbableElement.addEventListener('keydown', keyListener, false);
};

Here is an example call:

var modal = document.querySelector('.modal');
keepFocus(modal);

This only works for single elements and needs to be called when setting the focus of the element initially.

You can find the complete function as a Gist and use it from there if this serves you better.

Since we are the cool kids, we don’t even need jQuery to help us with any of that. The DOM’s ya friend, y’all!

Conclusion

As we can see it is not very hard to make a dialog accessible by using JavaScript. Nicholas Zakas’ blog post shows some pretty easy methods to create an accessible modal and this circular tabbing method helps to keep focus within the dialog.

If you ask yourself why you would want to do this, I recommend you watch one of Marco Zehe’s talks and read his blog posts on accessibility.

As always there are a lot of smart people who documented this before I did and had better ideas. If you know of any please tell me via Twitter what’s wrong with my snippet and let me make it better. Also I’m not really into accessibility which is why this all might be nonsense.

Update – 01. July 2013

Jörn Zaefferer pointed out that it’s not only Tab that needs to be observed but also Shift + Tab. Totally true since users might want to go backwards through the selected area of the page.

I’ve now updated the function to reflect this behavior. But let’s do a quick walk through the changes.

First I wrote a small polyfill for event.preventDefault(); so we can easily reuse the function throughout the event handler:

// Polyfill to prevent the default behavior of events
event.preventDefault = event.preventDefault || function () {
	event.returnValue = false;
};

Another thing that has changed is the fact that we will now use event delegation instead of a single event on the lastTabbableElement since we need to listen to the first element too. This was suggested by Rodney Rehm too.

One part of this is the listener that changes:

context.addEventListener('keydown', keyListener, false);

The other part is the handler function. We need to match event.target – the currently selected element – against the first and last tabbable element while we have to watch out for the shift key to be pressed. Luckily event.shiftKey tells us that. This code is inspired by the code from jQuery UI’s Dialog component.

// Move focus to first element that can be tabbed if Shift isn't used
if (event.target === lastTabbableElement && !event.shiftKey) {
	event.preventDefault();
	firstTabbableElement.focus();
 
// Move focus to last element that can be tabbed if Shift is used
} else if (event.target === firstTabbableElement && event.shiftKey) {
	event.preventDefault();
	lastTabbableElement.focus();
}

If we put this together, we get the desired behavior: Whether you use Tab or Shift + Tab in the selected part of the page the focus stays in it.
The Gist is available with the updated function.

Introducing CSS Modal

CSS Modals in action

In the last couple of months I’ve worked on several projects that needed an overlay with some content on it. Some front-end frameworks as for example Bootstrap refer to them as modals.
You can find a lot of implementations that do exactly what I search for but they all have one major drawback: They rely on JavaScript.

Yes, sure, everyone has JavaScript enabled these days but why use a technique that you don’t necessarily need for a given problem? Also most implementations have drawbacks when it comes to mobile devices and responsive web design in general or accessibility. Apart from that they add a lot of code, that is not necessary for a lot of pages. Others might add dependencies such as for example jQuery which you don’t need at all on your micro-site.

To tackle these problems I decided to write my own implementation of a modal that fulfills what I need.

Modals built out of pure CSS

CSS Modal is the result of this experiment.

Here is what is cool about it:

  • CSS Modal is built out of pure CSS while JavaScript is only for some sugar.
  • The modals are designed using responsive web design methods.
  • It is accessible, cross-browser, media-adaptive, small and fast!

Another cool thing is that you can use CSS Modal as Sass plugin and apply it to your custom classes using Sass placeholders.

Visit the website     View an example

Check out the website to get documentation and more examples. The project is on GitHub so if you use it and find bugs, please report them.

General feedback is also very welcome. Please tweet me!

Printing The Web

Printable Websites - some books

While it is possible to consume nearly all means of content on your smartphone or tablet it seems like the dream of a paperless office comes true for a lot of web developers.

But digital natives are not the only ones who are on the web. There are still some people that like to print web sites on paper. Once you are aware of that you might want to include a dedicated print stylesheet into web sites you build. Here is some advice on what you can do to get the best out of your page.

Disclaimer: This article was first published in the German Screen Guide Magazine #15 (September to December 2012, pages 77 to 79). This article features more content and better research.

The basics of a print style sheet should already be well known by most web developers. There are two possible ways to include CSS for print:

  • a separate file included in the HTML that carries all CSS for print media
    <link rel="stylesheet" media="print" href="css/print.css">

  • a special media query which targets print mode and is integrated into your regular stylesheet
    @media print { … }

The decision which way to go is pretty obvious: We do not want to have another request to the server for an extra style sheet and thus will embed the styles using a media query. With the help of preprocessors such as LESS or Sass and build systems it is easily possible to put these styles into separate files and concatenate them when needed for production.

Remove Clutter

In general focusing on the main content of a web page is very important when it comes to print style sheets. Remove unnecessary page elements such as navigation and the footer using display: none;. However you might not want to remove a logo that identifies your website from the printed version. (Maybe you have an optimized monochrome version that looks better when printing black and white – you can include this as a background-image. This can be overwritten via the user’s configuration though.)

Think about readable fonts and appropriate font sizes – in print you usually want to have a size not bigger than 12px for your body copy, but on screen 16px is totally appropriate. Furthermore it is important to print mostly dark colors on light background. It might be the best solution to use black as the default text color.
This is also more economical than printing other colors.

When in doubt, print the page while developing it to get a better feeling for the font setup.

Improve The Content

There are a couple of techniques to add more value to the content of a page. One is to add the URL of a link directly after the link text. Don’t do that for links that link to sections of your page or have JavaScript handlers, because it will not carry any meaning for the uninformed reader:

a[href]:after {
    content: " (" attr(href) ")";
}
 
a[href^="#"]:after,
a[href^="javascript"]:after {
    content: "";
}

This is also useful for the abbr element (for abbreviations) and its title attribute. (The same rule technically appies to acronym – thanks to Adrian Roselli).

abbr[title]:after {
    content: " (" attr(title) ")";
}

You can find a more detailed post about this technique here.

Edit: As Tim suggests in the comments it might be necessary to use word-wrap: break-word; on these elements as especially links can become pretty long and thus break you layout.

Remember that browsers normally display a header and footer line with some information about your site such as the URL it was printed from or the date. The user might have an option to remove those lines so you may want to include some link or a breadcrumb in the printed page so the reader can easily check back on the web if needed. Other methods outline embedding a QR code on the printed page. Adrian Roselli describes this method further.

In general most style sheets might be done with these few considerations. But there are some more helpers and CSS rules that can come in handy in certain cases.

A few weeks ago there was an interesing article at Smashing Magazine which has some more useful tips for dealing with links, images and so on. Check it out if needed.

Structuring The Page

Let’s dig a bit deeper.

The at-rule @page allows you to specify the structure of the page. Here is an example of how you can configure the margin of the page:

@page {
    margin: 2cm 1.5cm;
}

Furthermore it is possible to define styles via pseudo-classes. With :first for instance you target only the first page of a document, :left and :right target all even/odd pages (this depends on the direction of writing in a language). This can help you if you want to print a manuscript or magazine for example.

It is possible to name a property and apply it to differnet elements. This comes in handy if you want to print tables in landscape mode:

@page tables {
    size: landscape;
}
 
table {
    page: tables;
}

This is far more experimental and can not be used reliable. Check out this test case. Please see the specification for a more detailed explanation.

More information about the @page rule can be found at the Mozilla Developer Network.

With size you can specify the size of the sheet you want to print your document on. The initial value is auto which sets the width to a DIN A4 sheet with a size of 210 × 297 millimeters. You can target an expected DIN A5 sheet this way:

@page {
    size: 148mm 210mm;
}

Even though this is possibile you should let the printer defaults handle the size of the sheet, especially since DIN A4 is not used in the US for example.

Side note: Please be aware that it is still not possible to cut a sheet via CSS, thus it is only an expected size. I know this sucks! 3D printers might save us soon.

Page-Breaks

Both properties page-break-before and page-break-after specify when a page break occurs and when you do not want it to happen. For instance you most likely want to avoid page breaks after a headline:

h2 {
    page-break-after: avoid;
}

Possible values of page-break-before and page-break-after are:

  • auto – default value, no specified behavior
  • always – invokes a page-break
  • avoid – tries to avoid a page-break
  • left/right – single or double page-break to get the element to start on either the left of the right page, interesting when you want to print brochures or books.

Furthermore, there is the property page-break-inside which behaves similarly but only supports the values auto and avoid. While avoid specifies that there sould be no page-break within the element and auto does not specify a specific behavior.

Experimental Properties

The next few features are still in development or only supported by single browsers. Some of them are part of the (not really) new CSS Paged Media Specification.

Print What You See On Screen

The property -webkit-print-color-adjust: exact; only works in WebKit browsers (namely Chrome and Safari) and enables you to print a page exactly as it is displayed on screen. Mostly this means that you can print CSS backgrounds. But be careful, there is a bug when it comes to gradients: Gradients are not printed at all. Also it is not possible to define the property on the body element (Whaaaat? :/).

You need to use this property if you want to print a b/w-optimized logo as outlined earlier and you don’t want to include an image in the markup.

Other browsers such as Firefox allow users to specify whether they want to print background images and colors via an option in the print dialogue.

Widows And Orphans

To prevent single lines of text to be at the end of one page you can adjust how many lines have to be tied together with orphans. p { orphans: 3; } for instance requires at least three consecutive lines in a paragraph on the end of a page.

In contrast – only one line at the beginning of a new page – widows helps you out. So with article { widows: 2; } you will get at least two lines of text for an article on a new page.

Crop Marks And Page Bleed

Sometimes you need specific declarations on how to cut a sheet of paper. With marks it is possible to set marks via the values crop and cross while crop adds crop marks and cross adds fiducial marks.

If this property is set you can specify how far the printable area spreads out of the area defined by the aforementioned marks by using the property bleed while using one of the units defined in the values and units specification.

This property is part of the CSS Generated Content for Paged Media Module which is basically to really recognized by the browser vendors.

Boxes On Page-Break

The property box-decoration-break specifies how for example background, margin or border behave when the page breaks. There are two possible values for this property (also see the picture):

  • slice – default value, literally “slices” the box into two parts
  • clone – dupicates the styles that are applied to a box on each page

This is currently supported by Opera with the Presto Engine and will shortly be availabe in Google Chrome. Lennart Schoors wrote about this property a while ago on his blog Bricss.

In Firefox there is -moz-background-inline-policy which enables you to treat background images how you want to. But this is clearly only a partial implementation of box-decoration-break.

More On Browser Support

While the at-rule @page is supported by all major browsers except Internet Explorer 7 and was just implemented by Firefox a few months ago. Most other properties are far more complex:

  • You should use page-break-before and page-break-after only with its value always since the other values are not supported widely
  • page-break-inside is not supported in Internet Explorer 7.

You have to be aware that nearly all experimental properies lack support in most browsers and are only implemented by one major engine. For example orphans and widows are only supported in Internet Explorer since version 8 and Opera – which will soon be history as of their change to WebKit. marks and bleed is not implemented in any browser so far.

What Is Missing?

There are certain drawbacks when it comes to styling for print: Up until now there is no good possibility to define header and footer lines for your pages which would be very helpful for paginated printing. You can use pseudo elements of the body element which enables you to set a header and a footer on the first and last page. But this is by far not what is needed. You will run into this problem when you try to print tables: it is simply not possible without duplicate markup to print the thead of the table on each page (while repeating markup is not a real solution as you don’t know where a page breaks).

The funny thing is the specification of thead and tfoot states that it might be useful to repeat the elements on each page. Sadly no browser vendor implemented this yet.

But it is possible to create a solution for that. It could be a nice thing to implement JavaScript events that get invoked right before a page is printed. But as Simon Sapin states this is not really possible due to the mechanisms how browsers layout a page:

Page breaks happen during layout, much too late to do DOM manipulation (which invalidates and restarts layout). It’s really up to the layout engine to do this.

Also more properties for @page could be helpful to generate header and footer for each page.

Luckily the Paged Media Specification tries to tackle this problem. This specification has just become a Working Draft.

Here is an example on how you can implement a footer with the page count on every page:

@page {
    counter-increment: page;
 
    @top-center {
        content: "Headline, yo!"
    }
 
    @bottom-right {
        counter-increment: page;
        content: "Page " counter(page);
    }
}

The counter-increment property is a bit special with the keyword page – it increments automatically according to the specification, so you don’t need it at all.

That rocks, right?! Totally want this in browsers now.

Edit – 26.03.2013: Actually there is another possible implementation for fixed headers and footers using position: fixed; elements as Robert Weber researched. Unfortunately this only works in Firefox, Opera and Internet Explorer with several quirks. Please read his comment.

A Word On Mobile

These days it has become more and more popular to visit web pages from your smartphone or tablet but I have never seen anyone printing a web page from such a device.

I am not aware of a browser that has the ability to print a page. But maybe this will come in the near future. Let me know if you know more about this.

Edit – 25.03.2013: As Cãtãlin Mariş points out, iOS has a feature to connect to a wireless printer and print a website. This uses Apple’s AirPrint services.

The Server-Side

This post does not take any server-side rendering methods to create style sheets into account. However there are some several non-browsers, print-oriented CSS implementations: WeasyPrint, PrinceXML or AntennaHouse and others implement many CSS features that browsers don’t.

So take a look at these libraries if you are in need of more consitend

Conclusion

As it turns out it is possible to handle simple structured web pages with the provided properties for print stylesheets. But when it comes to more complex applications you will easily reach the end of these possibilities.

As a result of the work that the editors put into new specifications such as the Paged Media Spec we will be able to deal with better solutions in the future.

Thanks

A big thank you goes out to Adrian Roselli and Simon Sapin for providing very valuable technical feedback for this article. Apart from that I want to thank Thomas Caspers for proofreading the post.

Speaking Engagements, the .net-Awards and Freelancing

Here is a quick overview of my current status and why there are little updates in the blog. Also some great news.

Talking at Conferences

As you know, if you follow along my stuff, I spoke about coding guidelines at TalkOff Conference in Lille, France in January this year. The conference was organized very well and I had a lot of fun. Besides that I met a lot of great people. Thanks again for the invitation. You can find the slides here.

I am also very happy to be invited to UX Munich where I will speak about style guides in general and how you can be friends with designers. Check out the talk’s description on their website. There are a lot great people speaking at the conference as for example Vitaly Friedmann from Smashing Magazine and Nishant Kothary who was part of the team that redesigned Microsoft.com. Also Bastian Allgeier will be speaking, who wrote an article for The Nitty Gritty just recently.
This conference will take place in Munich, Germany and will be helt next week. So check it out quickly and get a ticket!

Later in April I will present at Front-Trends 2013 in Warsaw in Poland and yet again some top speakers of our industry will present there, too. Check out the speakers page to find Lea Verou, Faruk Ateş, Jake Archibald and a lot of others.

If you want me to speak at your conference, I’d be happy to submit a proposal. Just contact me.

.net-Awards Nomination

I am very happy to be one of the nominees of this year’s .net-Awards in the category “Young Developer of the Year”. Check out the website and vote what you like.
Thanks to everyone who proposed me to be nominated, this really means a lot to me. <3

Freelance Work

A couple of months ago I decided to leave /gebrüderheitz and do freelance work exclusively for some time starting in April. I want to focus a bit more on Open Source projects and work on some side-projects. I am really excited about the projects that I’ll be working on and about the re-organisation of my life.
The pipeline of actual client projects is still kind of free, so drop me a mail to info@drublic.de or use the contact form if you are interested in working with me. Please see the “Hire me” section on my website to get a quick overview of what I like to work on.

This all and some projects besides my normal work schedule keep me from updating my blog more often. I hope to write some more technical articles soon.
LOVE!

TakeOff Conference: Talking About Good Code

Yesterday (17. January 2013) I was talking at TakeOff Conference in Lille, France. I actually extended my talk from the Fronteer’s Jam Session “Writing Awesome Code” with lots of new stuff. So check out the slides. There will be a video with the actual talk that is not online yet. I will post it here when it is.

See slides

Just a few words concerning the conference: The organizers are doing a great job here and the speakers are really good. If you’re not here, you are missing out on something :)

The REM Fallback with Sass or LESS

Since a while now word has spread to use the CSS unit rem for font-sizes and values in CSS. Here I want to explain how you can use a fallback in Sass or LESS to get rem working in all browsers.

View Gist with mixins

Why rem?

Let’s look into what rem means. We know of the em unit which is relative to the font-size of the parent element it is defined on. This means if one of the parents in the DOM-tree changes its font-size, the font-size of the child element changes too. In contrast the rem unit is relative to the root element of the page (this means the html element). Thus it is possible to define a font-size once on the root and make all other sizes depending on this size. Please switch over to Snook’s blogpost explaining what rem is to get more information about it.

If you ask yourself why you should use em instead of px, Chris Coyier wrote an article on why he switched to em instead of pixels a while ago for nearly all properties using units in CSS. Read this to understand why em and thus rem is so important.

I would encourage you to use rem (or at least em) for properties like padding, margin and sometimes even width instead of pixels. It makes your design even more responsive.

The drawback of rem is that it is not supported in all browsers that are used, even though the support looks pretty good: Internet Explorer is capable of dealing with rem since version 9. The versions before need a fallback. It is supported on the major mobile browsers except Opera Mini. Let us have a look on how we can define such a fallback using Sass or LESS.

A Sass Mixin

In order to get the pixel-based auto-calculation working as a fallback we need to define the font-size as a variable in Sass or LESS.
The following examples are in Sass with the SCSS-syntax.

$main-font-size: 16px;

We can now use this default font size on the root element:

html {
  font-size: $main-font-size;

Now we define a mixin that provides a fallback pixel-based size of the property based on the variable we defined before and in rem for capable browsers.

@mixin x-rem ($property, $value) {
  #{$property}: $value * $main-font-size;
  #{$property}: #{$value}rem;
}

What the mixin does is, that it takes the $property and calculates the value in pixels. This simple mathematic function is part of Sass. The $value argument is a decimal digit.

I like to prefix my own mixins with x- to easily distinguish them from other mixins. This is a part of the Idiomatic CSS principles by Nicolas too. I think previously I prefixed them with a namespace (mostly it was the- as a prefix, so you get the-transition) – but since there is a better convention with Idiomatic CSS I switched to it.

This mixin can be called like in the following examples:

@include x-rem(font-size, 1.4);
@include x-rem(padding-left, 2);

The output that is being produced looks like this for the first example:

font-size: 22.4px;
font-size: 1.4rem;

You can use Sass’ round() function to get an integer output for the px-based output. But every browser is capable to round 22.4px by itself to 22px since it is not possible to display 0.4px after all. (LESS has the same function.)

A Few Words On The LESS Mixin

In LESS interpolation for properties is current not possible with version 1.3.x. The maintainers aim to include it in version 1.4. For the time being we need to define a workaround for properties which is basically a JavaScript function which returns a sting that consists of two properties instead of one, while the first one is - which is basically no property an thus disregarded by the browser. The second is the property that we want to use.

Here is the first line of the mixin:

-: ~`(function () { return ';@{property}: @{px-fallback}'; }())`;

This only works if the LESS compiler uses the actual JS library. It does not work with lessphp or other compilers that are not JavaScript based.

Final Words

And that is it. The mixin provides a decent fallback for rem-based sizes of all kind. Since CSS runs stable with this version of a fallback and overwrites the pixel-based value because of CSS’ cascade we can use it without any problems. It works in old Internet Explorers.

Life is easy with rem. So look at the Gist and use the rem-fallback-mixins.

Sass and LESS mixins

Credit

I want to mention that I first saw this technique used by Divya Manian a year ago (beginning of 2012) when working on the HTML5 Please API project. I am not sure who developed this technique or where it comes from. Please let me know if you have a link.

Addition: The Susy framework has a Sass mixin which lets you easily convert units including the rem unit and a fallback as described here. (Head-tip Fabian Beiner.)

Addition 2: Steffen wrote a Sass mixin which lets you use the short notation of properties like margin or padding. Even mixing values as px and rem is working. Cheers!

Working Draft Revision 100

Working DraftIt’s been over two years now – with our podcast Working Draft we have done 100 revisions. Congratulations to ourselves!

We recorded revision 100 on Monday and had a very special guest: Paul Irish. That’s why we recorded in English this time. The final podcast is now live and can be downloaded. Check it out and let us know what you think.

Listen to WD Revision 100

Here are the topics we talked about: