Design and Development

IE9 taught me something valuable today

By

Filed under: CSS, Web Development.

Recently, while working on an app project with one of my clients (MinistrySync – Events made Easy), I discovered some interesting things while testing for IE.

Normally, IE is the bane of my existence, and I have been known to rant and rave about how terrible it is to anyone who still chooses to use it.

Ugly IE9 Logo

But for once, IE actually forced me to learn something very interesting about Sass and the SMACSS to code structuring.

So here I was humming along testing our new app in Chrome, Safari, a few tweaks for Firefox… and then IE9…

As I pulled up the browser and loaded our first page, to my dismay basically none of my styles were being applied. It was very strange because everything was working fine in all the other browsers, and I knew that IE9 at least supported a few simple properties like background-colors on my buttons, which weren’t even showing.

After doing some research, I found other people were having similar problems with larger websites/apps. It turns out that IE9 and below has some very interesting limiting features they decided to implement.

Lovely IE9 quirks

  • – 4089 selector limit per file
  • – 289kb limit per file

So first off the 4089 selector limit per stylesheet – I have no idea why this is a feature of <= IE9, but for some reason they decided to implement it.

The real problem for us was the 289kb file size limit. Because we were running our styles in dev mode our stylesheet was around 411kb. Well, that’s fine I thought, just switch the flag to production, minify everything and we should be good to go, right?

After removing comments and minifying everything our file size went down to about 283kb. Yes, it should work now… actually not. For some reason IE still would not load our main stylesheet– probably due to the selector limit.

After talking with another developer, we both started to think that even though this was a large app, there is no way our stylesheet should still be so large. So I opened up the main.css.min file in sublime and started scrolling around looking for any clues.

As I was looking through the file, I noticed in Sublime’s Mini-Map that there was a huge mass of similar colors that belonged to class selectors. Scrolling down to the spot I was met with something so huge and ugly it surprised me!

Our App’s Structure

Now before I tell you what it was, I need to give you a little background on how we structure the styles in our app.

For our app’s modules like buttons, radios, checkboxes, navbars, forms, dropdowns etc. we are using OOSCSS/SMACSS principles to maintain a clean, reusable, easily maintainable code base. This means our classes are structured in the following matter:

.module
.module_with_long_name
.parent_module-child_module

.module--modified

// module skins

.module-primary
.s-module-alert (needs an s modifier at the front of the class if the skin is not easily understood)

A real life example might help a little more:

.btn
.btn--large

.btn-primary
.s-btn-ignite

    .btn-icon

In our actual code our module structure for modifiers will look as follows:

.btn {
    // styles
}
.btn--large {
    @extend .btn;
    // styles
}

Works great in theory, but in our real life application we found a few challenges.

1. If a module applies layout/style to a child element it will be added to all the modifier classes.

Consider our previous example of the button module.

.btn {
    // styles

    [class^="icon"] {
        // layout
    }
}
.form {
    .btn {
        // special form button layout
    }
}
.form--lrg {
    @extend .form;
    // form styles
}

In our initial docs on how to structure code, we thought it would be fine for the module to control how its children were laid-out. Here’s the problem with that approach:

For any modified form structures (.form–lrg) all the .btn layout classes will be applied again.

.form .btn, .form .btn [class^="icon"], .form .btn--large, .form .btn--large [class^="icon], .form .btn--small, .form .btn--small [class=^="icon"]

.form--lrg .btn, .form--lrg .btn--large, .form--lrg .btn--small

As you can see, this results in a massive amount of bloated code that we were not counting on.

In reality this extend behavior makes sense, because no matter what button size was used in our form, we wanted it to float to the right… but a better approach is to simply put a pull-right class on the buttons and keep your stylesheet much cleaner and smaller.

2. If a module extends a base element (a, p, strong) this will be applied to other modules.

In our app, our buttons used some of the same styles as our <a> (link) elements, so we thought it was a natural use of the @extend sass feature.

a {
    text-decoration: none;
    font-family: Arial;
    font-size: 15px;
}
.btn {
    @extend a;
    // styles

    [class^="icon"] {
        // layout
    }
}

Looks great in practice, but when you actually go in and inspect the stylesheet you will find something huge, something ugly, and very much not what you wanted.

[screenshot of code]

The button module that is extending the core <a> element seems logical, but in reality is a very bad idea. Every time you apply a style to an a element, that is say inside the from – it gets extended to include all your button classes that are extending each other!

.form {
    a {
        // styles
    }
}

The output would be as such:

.form a, .form .btn, .form .btn--small, .form .btn--lrg, .form .btn--purchase etc.

.form--lrg a, .form--lrg .btn, .form--lrg .btn--small, .form--lrg .btn--lrg, .form--lrg .btn--purchase

In our case by simply removing the @extend a from our button classes our stylesheet size went down 98Kb! Yes, IE should work now.

I loaded up the page again and yes, the our stylesheets were working! Now, that doesn’t mean my browser testing work is finished with lovely IE9… but at least we have our base styles working now!

Conclusion

These problems are somewhat connected because they both resulted from trying to apply layout styles to a modules children.

Here are the big takeaways from what we discovered:

  • Never extend a base element, it will come back to hurt you later.
  • Don’t apply layout classes to a modules children.

In conclusion, I learned that having constraints (289kb file size limit) can actually be a good thing because it forced me to investigate the output of my sass code and discover a massive problem.

Our main.css.min stylesheet is now down to a much leaner and faster – only 111kb! This is down from 283kb before we fixed this issue.

This is great news for our mobile users because the app will be runner a lot faster and people will be able to get their work done just that much faster – every second adds up in the long run.

Leave a comment

  • (will not be published)