Mobile-first and IE8 Solution – Introducing grunt-legacssy (Updated)

Update: v0.2.0 now supports legacyWidth option to target only matching media queries.

We all are now responsive and mobile-first. Happy, enjoying both.

Well, and then there are this 10 % of folks using IE8 who try to take the fun out.

(Why? IE8 does not support media queries and ignores anything inside them, which – generally – results in showing the mobile layout)

Current solutions

There are three main ways to solve this I am aware of:

Response JS (or similar)
A (jQuery) polyfill emulating the behaviour.
The problem? It is a JavaScript code, thus takes time to execute. One more HTTP request (?).

parameters in preprocessors (see in SASS)
Generated stylesheets differ according to the settings.
The problem? It is heavily dependent on the preprocessor. Unusual code segments are needed.

Media query inside <link>
Special stylesheets for each media query.
The problem? More HTTP requests. All rules for each media query has to be together which is non-modular.

My solution

I took what I found best in all three of them and managed not to have (the same) problems.

The magic is that during the build process a duplicate stylesheet with flattened media queries is created.

Features

  • Works
  • Clean, universal, hack-free
  • Language independent
  • Code style independent
  • Only one HTTP request (in any browser)

Example

Let’s say we have the following CSS:

body {
  margin: 0;
  padding: 0;
}

@media only screen and (min-width: 768px) {
  h1 {
    font-weight: bold;
  }
}

Then the stylesheet with flattened media queries would look like this:

body {
  margin: 0;
  padding: 0;
}

h1 {
  font-weight: bold;
}

The usage is simple, taking advantage of conditional comments we give the flattened file to IE8 and lower and the original file to the rest:

<!--[if lte IE 8]>     <link rel="stylesheet" href="css/style-legacy.css"> <![endif]-->
<!--[if gt IE 8]><!--> <link rel="stylesheet" href="css/style.css"> <!--<![endif]-->

The tool – legaCSSy

To keep it simple as possible the flattened CSS should be generated automatically on build. The most widely used task runner in front-end community is – without a question – Grunt. That is why I made the tool as a Grunt plugin called:

grunt-legacssy

The description reads “Fix your CSS for legacy browsers”. Where, of course, legacy browsers means Internet Explorer 8 and lower.

Install with:

npm install grunt-legacssy --save-dev

In your Gruntfile.js add the configuration:

grunt.loadNpmTasks('grunt-legacssy');

grunt.initConfig({
  legacssy: {
    files: {
      'css/style-legacy.css': 'css/style.css',
    },
  },
})

The only available option in the present is stripMediaQueries, which is true by default.

Source files can be an array in which case they are concatenated before processing.

Grunt-legacssy does not provide CSS minification, use grunt-contrib-cssmin or grunt-yui-compressor instead.

More (updated) information is on the project page.

Forks and improvement ideas are welcomed!

Possible problems and future plans

The current version (v0.1.0) is pretty dumb. It actually flattens every @media rule. Yes, that is even print styles etc. Also legacy browsers will get the style for the highest resolution break point (if you practice progressive enhancement) which is not always desirable.

The idea is that in the options one could specify the legacy width – the tool would then include styles only in matching @media rules. This is planned for the public v1.0.0.

Update: Both – flattening only some media queries and legacy width option – is now included in v0.2.0!

Another idea – an optimization – is some kind of RE-prefix-free: remove rules old browser can not understand (e.g. those starting with a -webkit- prefix).

Please let me know in the comments if you tried it on your project, discover an error or have a question!

My Speech at Prague’s WebExpo

Just confirmed: on I am presenting at WebExpo 2013 in Prague!

The title reads:
How to Turn Your Ugly Old CSS into a Clean Future-Ready Beauty

Oh, so…

What is it going to be about?

About CSS, of course, and what I learned to be the most effective way of writing it.

Or to cite myself [sic] from the website:

A year ago I inherited 10,000 lines of styles. With no documentation. With long slow selectors. And with a lot of unused rubbish. I decided to change that.

I will share my method, several useful utilities, and some fails I experienced. Alongside with reasons why everyone should take care about their CSS.

My answer to the interview question ‘What is the talk about?’

It would be great to see you shortly after lunch on Friday 20th September in the audience.

Bonus No. 1

Here, enjoy this exclusive preview of the introductory slide:

Pre-WebExpo Exclusive preview

Note: I did fall in love with this brilliant font – Planer – I bought especially for these slides (but plan big with it).

Bonus No. 2 (the better one)

When I said I would appreciate your presence at my presentation I really meant that.

For the first three curious developers I have a 20 % discount on conference tickets (the link gets you directly to the ticket order or you can insert this code C45KMD during checkout).

Tips for foreigners

There is a major one tip (to rule them all): Come to Prague!

I am serious.

Prague is beautiful.

Flights are cheap (if you book early – as in, … now).

And if you find accommodation using Airbnb (affiliate, you get €19 off on your first trip) you will not only save same money but experience the true Prague.

Had you choose some apartment in Vršovice I can meet you and accompany you on the way to the conference. Plus recommend you good sightseeing in Prague (including the best pubs).

P.S. If you have questions or even suggestions to the speech feel free to write in the comments or write me on Twitter.

Using HTML Entities in Before and After Content

I came across interesting use of content property of ::after pseudo-element.

There was a requirement to append “»” (= &raquo; = right-pointing double angle quotation mark) to “show more” links.

First thought was to use something like:

.show-more:after {
    content: " &raquo;";
}

But as content is a generated content entities are not processed.

I did not want to use the character itself for the obvious reason.

After some research I found out it is possible to use unicode hexadecimal notation – e.g. “»” can be written as \bb.

Demo

.show-more:after {
    content: "\a0\bb"; /* space + » */
}
<a href="…" class="show-more">Show more</a>

Result: Show more

Notes

  • Sure one can use any UTF-8 character (space = \a0, …)
  • \bb, \BB, \00bb and \00BB are all equivalent.
  • Excellent support: IE8+ has full support.
  • Welcomed by-product: the generated content is not selectable (try it yourself above).

Yeoman with LESS Bootstrap

Yeoman – if you haven’t heard of it go check it out now! – is an awesome tool for front end developers. And I love it.

However LESS is my preference over SASS, which makes using Yeoman discomfortable. For my and the fellow LESSers’ future use I made a generator, which I proudly present to you, called

generator-lessapp

The usage is actually very easy: there is just one extra step of downloading the generator.

Do Not Put @font-face Inside @media Query

“Roses are red,
Violets are blue,
use mobile first,
and icon fonts too!”

This was told me many times by many people as a universal truth. (Not always in a form of a poem)

I am not a fan of using it unthinkingly every time. However I decided to give it a go in the new project.

Going smart

OK, so now I have the mobile version, let’s do the desktop design. As I did not need icons in the mobile I shall include them now, right?

@media only screen and (min-width: 720px) {
    @font-face {…}
}

It works!

Everywhere but IE9

IE9 shows squares – as the only one. WTF?

The font is rendered on others sites, so it must work here.

What happens when @font-face is moved to the top of CSS?

It works!

Why, IE? Why?

We are used that IE does what it want, but this time there is a rational explanation:

At-rules inside @media are invalid in CSS2.1.

CSS 2.1 Specification

This line is not in the current CSS3 Specification. And since IE9 does not know much CSS3 – it refuses to load the font.

Simple.

Update: Old Firefox (e.g. v10.0) behaves the same.

My 4 Steps Guide to Switch from CSS to LESS in 3 minutes

Notes:

  • This is a kind of proof of concept how easy it is to switch. In real development I would use grunt with recess to automate the task.
  • Yes, you need to have node.js and npm installed. But who doesn’t nowadays?
  • LESS is a choose we made in our company some time ago. SASS (especially with Yeoman) or Stylus are equally good to use (if not much better).
  • Time tracking is a nice feature of smart commits.
  • The script was tested in Mac OS X 10.8, but it should work in any UNIX or compatible system.